SPF terms and what they cost
| Term | Matches | Lookups |
|---|---|---|
| ip4:203.0.113.0/24 | An IPv4 address or network | 0 |
| ip6:2001:db8::/48 | An IPv6 address or network | 0 |
| a | The domain's own A/AAAA addresses (a:host for another name) | 1 |
| mx | The addresses of the domain's MX hosts | 1 |
| include:_spf.example.net | Whatever that domain's SPF record allows | 1 + its own |
| exists:%{i}.x.example | A lookup built from macros; used by some large senders | 1 |
| ptr | Reverse DNS — deprecated by RFC 7208, do not use | 1 |
| redirect=_spf.example.com | Use that record instead; ignored when the record has an all | 1 |
| -all ~all ?all | Everything not matched: fail, soft fail, neutral | 0 |
A qualifier in front of a mechanism sets its result: + pass (the default, never written), - fail, ~ soft fail, ? neutral. Receivers read the terms from left to right and stop at the first match.
Getting under ten lookups
- 1Remove what you no longer send with
Every service you ever connected left an
include:behind. If you no longer send through it, delete the include — it costs lookups and allows a stranger’s servers to send as you. - 2Replace a and mx with addresses
Your own mail server’s address does not change often.
ip4:203.0.113.25costs nothing whereaandmxcost one lookup each. - 3Send bulk mail from a subdomain
Newsletters and notifications can use their own subdomain —
news.example.com— with its own SPF record, so their includes no longer count against the main domain’s ten.
“Flattening” — replacing an include with the address ranges it currently stands for — also works, but the ranges belong to the provider and change without notice. A flattened record needs a job that keeps it up to date, or it starts failing your own mail.
Common records
; Google Workspace
example.com. TXT "v=spf1 include:_spf.google.com ~all"
; Microsoft 365
example.com. TXT "v=spf1 include:spf.protection.outlook.com -all"
; your own server, plus Google Workspace
example.com. TXT "v=spf1 ip4:203.0.113.25 include:_spf.google.com ~all"
; a domain that sends no mail at all
example.com. TXT "v=spf1 -all"A domain that sends no mail is worth protecting too, because it is easier to spoof than one that does: pair v=spf1 -all with a DMARC policy of p=reject and a null MX record (0 .). The DMARC checker shows whether the policy is in place.
Check it by hand
dig example.com TXT +short | grep spf1
dig _spf.google.com TXT +short # follow an includeFrequently asked
What is an SPF record?
A TXT record on the domain that starts with v=spf1 and lists the servers allowed to send its mail: address ranges (ip4:, ip6:), the domain's own A or MX hosts, and other domains' lists pulled in with include:. A receiving server compares the address that connected with the list and gets pass, fail, soft fail or neutral; the all at the end decides what happens to everything not listed.
What is the SPF limit of ten DNS lookups?
RFC 7208 lets a receiver make at most ten DNS lookups while evaluating one SPF record. include, a, mx, ptr, exists and redirect each cost one, and the includes inside an include count too; ip4, ip6 and all cost none. On the eleventh the result is permerror, which most receivers treat as a fail. Remove includes for services you no longer use, list your own servers with ip4:/ip6: instead of a or mx, and ask a provider for a narrower include before copying its ranges by hand — copied ranges go stale when the provider changes them.
Should an SPF record end in ~all or -all?
Both reject spoofing once DMARC is enforced, because DMARC then decides what happens to failing mail. ~all (soft fail) is the common choice and forgives a forwarded message; -all (fail) is stricter and lets receivers without DMARC reject outright. Never publish +all, which allows every server on the internet, or end without an all, which leaves unlisted servers at neutral.
Can a domain have two SPF records?
No. With more than one v=spf1 record every SPF check of the domain ends in permerror. When a new service asks you to add its SPF record, add its include: to the existing record instead.
Does SPF check the From address people see?
No. SPF checks the envelope sender — the Return-Path, which bulk mail services usually set to their own domain — and the server's HELO name. DMARC is what ties the result to the visible From address, by requiring the two domains to match.