What is an SPF record?
An SPF (Sender Policy Framework) record is a DNS TXT record that lists the servers allowed to send email for a domain. Receiving mail servers look it up, compare it with the IP address that delivered the message, and use the result — pass, fail or softfail — to help decide whether the mail is genuine.
Why the 10-lookup limit matters
SPF is defined in RFC 7208. Section 4.6.4 caps the number of DNS queries a receiver will make while evaluating one record at 10. The limit counts every include, a, mx, ptr and exists mechanism and the redirect modifier — including the ones buried inside other providers' records. ip4, ip6 and all cost nothing.
Going over is not a soft warning. The receiver stops and returns a PermError, which most mailbox providers treat the same as having no SPF at all. Because the count depends on records you do not control, a domain can cross the limit without anyone touching its DNS: a provider adds one more nested include and your mail starts failing.
This checker walks the whole tree, the way a receiving server does, and shows the cost of each branch so you can see which provider is spending your budget.
How to read the results
| Check | Pass | Fail |
|---|---|---|
| Record present | Exactly one TXT record starts with v=spf1 | None, or more than one (two records are a PermError) |
| DNS lookups | 10 or fewer across the whole include tree | 11 or more — PermError |
all mechanism | Ends in -all (fail) or ~all (softfail) | +all authorizes every server on the internet; ?all asserts nothing |
| Includes resolve | Every include: target publishes its own SPF record | A target with no SPF record is a PermError |
| No loops | No record includes itself, directly or through another | A loop can never finish evaluating |
ptr mechanism | Not used | Present — slow, unreliable and discouraged by the RFC |
The tree view lists each mechanism in evaluation order with the lookups it costs. A number beside an include is the total for that provider, nested lookups included.
How to fix common SPF problems
Too many DNS lookups. Work through these in order — the first two usually fix it:
- Remove includes for services you no longer send through. Old marketing and helpdesk tools are the usual culprits.
- Replace
aandmxwith the literalip4:/ip6:address when the server's IP is stable. Each one saves a lookup. - Move a bulk sender to a subdomain such as
mail.example.comwith its own SPF record. Each subdomain gets its own budget of 10. - Only as a last resort, flatten an include into its IP ranges. Flattened records go stale when the provider changes addresses, so they need monitoring.
Two SPF records. Merge them into one. A domain that sends through Google Workspace and SendGrid needs a single record:
v=spf1 include:_spf.google.com include:sendgrid.net ~allNo all at the end. Without all or a redirect, the result for unlisted servers is neutral, which protects nothing. Add ~all while you confirm every legitimate sender is listed, then move to -all.
A domain that never sends email. Publish a record that says so, so nobody can use it for spoofing:
v=spf1 -allExamples of valid SPF records
| Setup | Record |
|---|---|
| Google Workspace only | v=spf1 include:_spf.google.com ~all |
| Microsoft 365 only | v=spf1 include:spf.protection.outlook.com -all |
| Own mail server plus Mailgun | v=spf1 ip4:203.0.113.25 include:mailgun.org ~all |
| Sends no mail | v=spf1 -all |
What SPF does not cover
- Forwarding. A forwarded message arrives from the forwarder's IP, so SPF fails even though the mail is legitimate. DKIM survives forwarding; SPF does not.
- The visible From address. SPF alone lets an attacker pass with their own domain in the envelope while showing yours in From. DMARC alignment closes that gap.
- Message content. SPF says nothing about whether a message was altered in transit. That is DKIM's job.
Since February 2024, Google's sender guidelines require SPF or DKIM from every sender and all three — SPF, DKIM and DMARC — from anyone sending 5,000 or more messages a day to Gmail accounts.