Sender Policy Framework (SPF) is a DNS record that lists which mail servers are allowed to send email using your domain. A receiving mail server can compare the connecting server's IP address against that list and decide how much to trust the message. SPF is simple in concept, but small syntax mistakes and a hidden lookup limit cause a lot of real-world failures. The current specification is RFC 7208.
What SPF actually checks
This is the part most people get wrong. SPF does not check the "From" address you see in your email client. It checks:
- the envelope sender, also called the MAIL FROM or return-path address, which the sending server gives during the SMTP conversation and which is used for bounces; and
- optionally, the HELO/EHLO name the sending server announces.
The envelope sender and the visible From address are often different, for example when a newsletter platform or ticketing system sends on your behalf using its own bounce domain. An attacker can pass SPF for their own domain in the envelope while putting your domain in the visible From line. Closing that gap is the job of DMARC, which requires the checked domain to align with the From address. See What DMARC does.
Anatomy of an SPF record
SPF is published as a TXT record at the domain used in the envelope sender:
example.com. 3600 IN TXT "v=spf1 ip4:192.0.2.0/24 ip6:2001:db8::/32 mx include:_spf.example.net -all"
Reading left to right:
v=spf1identifies the record as SPF. It must come first.- A series of mechanisms, each describing a set of allowed senders.
- A final
allmechanism that says what to do with everything else.
Receivers evaluate mechanisms in order and stop at the first match.
Mechanisms
ip4:andip6:match an address or range directly. They need no DNS lookups.amatches the IP addresses in the domain's A or AAAA records (or another domain's, asa:mail.example.com).mxmatches the addresses of the domain's MX hosts.include:evaluates another domain's SPF record and matches if that record passes. This is how you authorize third-party senders.exists:matches if a given name has an A record, used for advanced macro-based setups.ptrmatches based on reverse DNS. RFC 7208 discourages its use because it is slow and unreliable.allmatches everything and belongs at the end.
There are also two modifiers: redirect= hands evaluation to another domain's record when nothing else matched, and exp= points to an explanation string for rejections.
Qualifiers
Each mechanism can carry a qualifier that sets the result when it matches. If none is given, + is assumed.
+pass: the sender is authorized.-fail: the sender is not authorized.~softfail: probably not authorized; accept but treat with suspicion.?neutral: the domain makes no assertion.
-all, ~all, ?all and +all
The qualifier on the final all sets your policy for servers you did not list:
-allsays anything not listed should fail. It is the clearest statement, and appropriate once you are confident every legitimate sender is included.~allsays unlisted senders should softfail. It is common during setup and is a weaker statement on its own. Once DMARC is enforced, the difference matters less, because the DMARC policy then decides what happens to unauthenticated mail.?allsays nothing useful about unlisted senders. It offers little protection.+allauthorizes every server on the internet to send as your domain. It defeats the purpose of SPF and should never be used.
For a domain that sends no email at all, publish a record that authorizes nothing:
parked.example.com. 3600 IN TXT "v=spf1 -all"
Only one SPF record per name
A domain name must have at most one SPF record. If a receiver finds two TXT records starting with v=spf1 at the same name, the result is a permerror, and many receivers then treat the message as having no valid SPF.
This usually happens when a new service's setup guide says "add this SPF record" and someone adds a second record instead of merging. The fix is to combine them:
Wrong:
"v=spf1 include:_spf.example.net -all"
"v=spf1 include:mail.example.org -all"
Right:
"v=spf1 include:_spf.example.net include:mail.example.org -all"
The dedicated SPF record type (type 99) was deprecated; SPF should be published only as TXT.
The 10-DNS-lookup limit
To stop SPF evaluation from being used to generate floods of DNS traffic, RFC 7208 limits the number of DNS-querying terms to 10 per evaluation. The following each count toward the limit:
includeamxptrexists- the
redirectmodifier
ip4, ip6 and all do not count, because they need no lookups. Crucially, the count is cumulative across nested includes. If you include a provider whose record itself includes three others, all of them count. Exceed 10 and the result is a permerror, which is effectively the same as having no SPF.
There are related limits, too: an mx or ptr mechanism must not need to look up more than 10 names on its own, and receivers should give up after more than two void lookups, meaning lookups that return no records or a name that does not exist.
Ways to stay under the limit:
- Remove includes for services you no longer use.
- Replace
aandmxwith explicitip4/ip6ranges where addresses are stable. - Use subdomains for different senders, such as a separate envelope domain for marketing mail, each with its own SPF record.
- Treat "SPF flattening" services with care: replacing includes with lists of IP addresses works until the provider changes its addresses.
Other practical points
- Long records. A single TXT string is limited to 255 characters. Longer SPF records must be split into multiple quoted strings within one record, which receivers join together.
- Forwarding breaks SPF. When mail is forwarded, the forwarding server's IP address is not in the original domain's SPF record. This is one reason DMARC also accepts DKIM, which survives forwarding.
- Subdomains are separate. An SPF record at example.com does not cover mail.example.com's envelope; each name needs its own if it is used.
Check it yourself
- SPF Checker parses your record, expands includes, counts DNS lookups against the limit and warns about multiple records,
+alland other mistakes. - DMARC Checker shows whether a DMARC policy is in place to protect the visible From address.
- Email Security Checker reviews SPF, DMARC, MX and related records together for an overall picture.