Free SPF Checker
Validate an SPF record, count every nested DNS lookup through the full include chain, and catch the RFC 7208 ten-lookup limit before receivers do. Also flags multiple SPF records, deprecated mechanisms and dead includes. No signup.
How it works
Enter a domain
We query the root TXT records and find any record starting with v=spf1.
Recursively count lookups
Every 'include:' triggers a sub-lookup. We walk the chain and tally the total.
Get a clean verdict
Mechanisms, qualifiers, lookup count, and a list of issues — color-coded by severity.
What counts toward the 10-lookup limit, and what does not
Almost every broken SPF record in the wild is
broken the same way: it exceeds ten DNS lookups and receivers return permerror, which
they treat as an SPF failure even though the record is perfectly sensible to read. The
limit comes from RFC 7208 section 4.6.4 and it is a hard cap, not a guideline.
The part people get wrong is which mechanisms are charged:
| Mechanism | Costs a lookup? | Note |
|---|---|---|
include: | Yes, plus everything inside it | The usual culprit. The cost is the whole chain, not one. |
a, mx | Yes | mx is worse than it looks: it also resolves each MX host. |
ptr | Yes | Deprecated by the RFC. Delete it. |
exists: | Yes | One each. |
redirect= | Yes | Charged like an include, and it replaces your policy. |
ip4:, ip6: | No | Free. This is what flattening trades toward. |
all, v= | No | Free. |
So a record with eight include: entries is not at eight of ten. It is at eight plus
whatever those includes nest, and that is usually where the budget goes.
There is a second, quieter cap in the same section: more than two "void" lookups (ones
that return NXDOMAIN or no answer) is also a permerror. Includes pointing at
providers you stopped using years ago are the common cause, and no error surfaces until
a receiver enforces it.
What each provider actually costs you
The numbers repeated in most SPF guides are stale. These were measured directly with
dig on 2026-08-16, counting the include itself plus everything it nests:
| Provider | Include | Lookups |
|---|---|---|
| Google Workspace | _spf.google.com | 1 |
| Microsoft 365 | spf.protection.outlook.com | 1 |
| Amazon SES | amazonses.com | 1 |
| Mailchimp | servers.mcsv.net | 1 |
| Mandrill | spf.mandrillapp.com | 1 |
| Zendesk | mail.zendesk.com | 1 |
| Intercom | mail.intercom.io | 1 |
| Mailjet | spf.mailjet.com | 1 |
| Salesforce | _spf.salesforce.com | 2 (include plus an exists:) |
| SendGrid | sendgrid.net | 2 (nests ab.sendgrid.net) |
| HubSpot | _spf.hubspot.com | 3 (nests SendGrid's chain) |
Two things worth pulling out. Google Workspace is widely documented as costing four
lookups because _spf.google.com used to fan out to three _netblocks records; it is
flat today, so that advice now overstates your usage by three. And HubSpot costs three
rather than one because it includes SendGrid, which includes its own subrecord. If you
run both HubSpot and SendGrid directly, you are paying for that chain twice.
Providers change these records without notice, which is the argument for re-running the check rather than trusting any table, including this one.
What to do when you are over the limit
In rough order of how much they help against how much they cost you:
- Delete includes you no longer use. Most over-limit records are carrying two or three dead vendors. This is free and it is usually enough.
- Replace
aandmxwith explicitip4:entries. Same result, zero lookups, at the cost of having to update them when the addresses move. - Move a sender to its own subdomain. Marketing mail from
mail.example.comgets its own independent budget of ten lookups, because the limit is per record. This is the cleanest fix and the most underused one. - Flatten the record. Resolving every include down to
raw
ip4:blocks makes the lookup count near zero. The honest cost: you have taken ownership of IP ranges the provider expects to change, and when they do, your mail fails silently until someone re-flattens. If you flatten, automate the refresh.
SPF on its own does very little
SPF authenticates the envelope sender, not the From: header the recipient sees, so a
message can pass SPF and still be a convincing forgery. What closes that gap is
DMARC, which requires the authenticated domain to align with the
visible From: domain and lets you publish a policy for failures.
The practical sequence is SPF, then DKIM,
then DMARC at p=none while you read reports, then enforcement. Check the other two
with the DKIM record checker and the
DMARC record checker.
From the command line
Keyless, no signup:
curl -s "https://api.domainee.dev/v1/tools/spf-record-checker?domain=example.com" | jq
The response includes the parsed mechanisms, the recursive lookup count and a list of issues by severity. Rate limits are per IP and there is no uptime commitment, so it fits scripts and audits rather than a production dependency.
Domainee is a custom domains API for SaaS with a native MCP server, 50 domains and 100 GB free. Mail authentication and web custom domains are separate problems; this tool covers the first, the docs cover the second.
Frequently asked questions
Why does the 10-lookup limit matter?+
RFC 7208 §4.6.4: if SPF resolution exceeds 10 DNS lookups, receivers must return permerror. That means your messages get treated as if SPF failed even when the record is fine in spirit.
Which parts of an SPF record cost a lookup?+
include, a, mx, ptr, exists and redirect all cost at least one each, and include and redirect also cost whatever they nest. ip4, ip6 and all are free. That's why replacing includes with explicit ip4 ranges (flattening) fixes an over-limit record, and why counting your includes alone understates your real usage.
I have multiple SPF records — is that bad?+
Yes. RFC 7208 requires exactly one. Multiple SPF records cause receivers to permerror. Merge them into a single record.
What's the difference between -all, ~all, and ?all?+
-all = hard fail (reject), ~all = soft fail (mark suspicious), ?all = neutral (no action). Use ~all while rolling out, -all in steady state. Never use +all.
What about 'redirect=' modifiers?+
redirect= replaces the current SPF policy with another domain's. We follow it and count its lookups too.
Should I flatten my SPF record?+
Only as a last resort, and only if you automate the refresh. Flattening resolves every include down to raw IP ranges, which drops your lookup count to near zero but transfers ownership of those ranges to you. When the provider rotates IPs (and they do, without notice) your mail starts failing silently. Deleting unused includes or moving a sender to its own subdomain are safer fixes.
Building a SaaS that needs custom domains?
Domainee is the API for adding customer custom domains to your product. One CNAME, automatic TLS, no DevOps to staff.
50 custom domains and 100 GB bandwidth free, forever.
More free tools
SSL
Free SSL Certificate Checker
View issuer, validity, expiration countdown, and certificate chain for any domain.
DNS
Free DNS Record Lookup
Check A, AAAA, CNAME, MX, TXT, NS, and SOA records for any domain instantly.
Domain
Free WHOIS Lookup
View registrar, creation and expiry dates, name servers, and registration data for any domain.
DNS
Free CNAME Lookup & Generator
Validate CNAME records and get provider-specific setup instructions for custom domains.
HTTP
Free HTTP Header Checker
Inspect response headers, security headers, caching, redirects, and get a security grade for any URL.
DNS
Free DNS Propagation Checker
Query DNS servers across multiple global locations to verify your DNS changes are live.