Module 3: Email authenticationLesson 8 of 136 min read
SPF records explained: mechanisms, qualifiers and the 10-lookup limit
Nothing in basic email stops a server from claiming to send for any domain. SPF, the Sender Policy Framework, lets a domain owner publish which servers are allowed to use the domain when sending. Receiving servers check the connecting server's IP address against that list. The record is short, but a few rules, above all the limit on DNS lookups, catch out many domains that use several email services.
What SPF actually checks
RFC 7208 defines SPF as a check on two identities from the SMTP conversation: the MAIL FROM address, also called the envelope sender or return path, and the name the server gives in HELO or EHLO. It does not check the From address you see in your mail app. Linking the visible From to SPF is the job of DMARC, covered in its own lesson.
A domain publishes exactly one TXT record starting with v=spf1. RFC 7208 says a domain must not have multiple SPF records, and if a receiver finds more than one, the result is permerror, a permanent error.
Mechanisms and qualifiers
The record is a list of terms read from left to right. Each mechanism tests the sending IP address; the first one that matches decides the result. The common mechanisms are:
- ip4 and ip6: an address or range, such as ip4:192.0.2.0/24.
- a and mx: the addresses of the domain's A/AAAA or MX hosts.
- include: run another domain's SPF record and match if it passes. Email services publish one for their customers.
- all: matches everything, so it goes last and sets the default.
- ptr and exists: rarely needed; RFC 7208 marks ptr as do not use.
Qualifiers in front of a mechanism
+ pass (the default when nothing is written), - fail, ~ softfail, ? neutral. RFC 7208 calls softfail a weak statement that the host is probably not authorized. So -all says reject what isn't listed, ~all says treat it as suspicious, and +all authorises the whole internet.
The 10-lookup limit
Some terms need a DNS query when they are evaluated. RFC 7208 lists them: the include, a, mx, ptr and exists mechanisms and the redirect modifier. An SPF check must stop after 10 of these, counting everything inside included records too, and return permerror. The ip4, ip6 and all mechanisms cost nothing.
There is a second limit for lookups that find nothing. RFC 7208 calls a query that returns no answers or NXDOMAIN a void lookup, and recommends that receivers return permerror after more than two of them. An include pointing at a domain that no longer has SPF counts as one.
Counting lookups
Record: v=spf1 ip4:192.0.2.0/24 mx include:_spf.mailer.example.net include:spf.crm.example.org -all. Top level: ip4 0 + mx 1 + two includes 2 = 3. Inside _spf.mailer.example.net: three more includes = 3 (total 6). Inside spf.crm.example.org: a 1 + two includes 2 = 3 (total 9). Adding a helpdesk service whose record itself holds two includes costs 1 + 2 = 3 more: 12 lookups, over the limit, so every message gets permerror.
Fixing a record that is over the limit
Count first, because nested includes are invisible in your own record. Then reduce:
- Remove services you no longer send through: an include for an old newsletter tool still costs lookups.
- Replace a and mx with ip4 or ip6 ranges when your own servers' addresses are stable.
- Send bulk or marketing mail from a subdomain such as news.example.com with its own SPF record, so the two lists don't add up.
Why SPF alone is not enough
SPF breaks when mail is forwarded. The forwarding server's address isn't in the original domain's record, and RFC 7208 notes that forwarders would have to rewrite the MAIL FROM into their own domain to avoid it. It also says nothing about the From header people read.
That is why large mailbox providers ask for more than SPF. Google's guidelines require SPF or DKIM from all senders and SPF, DKIM and DMARC from bulk senders, and recommend that SPF include all of a domain's senders. Yahoo requires bulk senders to implement both SPF and DKIM and publish a DMARC policy.
See a real SPF record evaluated. Check DNS lookups against the limit of 10, Lookups that found nothing against 2, and open Includes, followed to see where each lookup comes from. Mail from servers not listed shows what the record's all rule does.
SPF checkerQuick check
Three questions. Pick an answer to see why.
A record reads v=spf1 ip4:198.51.100.0/24 include:a.example.net include:b.example.net ~all, and each included record contains two more includes. How many DNS lookups does it use?
Show the answer
Answer: 6 2 top-level includes + 2 × 2 nested includes = 6. ip4 and all cost nothing.
What happens when a domain publishes two TXT records that both start with v=spf1?
Show the answer
Answer: SPF returns permerror, a permanent error RFC 7208: if more than one record is found, check_host() produces permerror.
Why can a message that is legitimate fail SPF after being forwarded?
Show the answer
Answer: The forwarding server's IP address isn't listed in the original sender's SPF record SPF checks the connecting server; a forwarder sends from its own address, which the original domain never listed.
Standards, not guesses
These guides explain how the internet's plumbing works, using the published standards (RFCs) and official documentation. Each guide shows the date it was last checked.
Sources
- RFC 7208: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email
- Google Workspace Admin Help – Email sender guidelines
- Yahoo Sender Hub – Sender requirements and recommendations
Last checked October 28, 2026