~/blog/spf-10-lookup-limit
> The SPF 10-lookup limit: what it means and how to fix it
· spf · email · dns · deliverability
Section 4.6.4 of RFC 7208 caps an SPF record evaluation at ten DNS lookups. Go over and the evaluator returns permerror, which DMARC treats as a hard authentication failure. Most deliverability problems that look like "SPF is broken" are actually "SPF is evaluating but hitting the limit."
Why the limit exists
SPF records can nest: an include: mechanism pulls in another domain's SPF, which can itself contain more include: or a/mx/exists/ptr lookups. Without a cap a single lookup could trigger unbounded DNS traffic. Ten is the RFC's chosen balance between expressive-enough-to-be-useful and bounded-enough-to-be-safe.
The count includes:
- every
include:mechanism - every
aandmxmechanism (eachmxcharges one for the MX lookup plus one per returned host) - every
existsmechanism - every
redirect=modifier ptr(which is deprecated and you should remove anyway)
It does not include the initial TXT lookup for the SPF record itself, ip4: and ip6: mechanisms (those are inline), or the all mechanism.
How include chains explode
The sneaky part: a include:spf.google.com counts as one lookup in your record, but when the evaluator resolves spf.google.com, its record contains more include: mechanisms. Those each count against your budget too.
A real-world example: Google Workspace's _spf.google.com expands to include:_netblocks.google.com, include:_netblocks2.google.com, include:_netblocks3.google.com. That is four lookups from one include:spf.google.com. Add Microsoft 365's include:spf.protection.outlook.com (one lookup), SendGrid's include:sendgrid.net (one), Mailchimp's include:servers.mcsv.net (one), and a couple of transactional senders and you are at the limit before you have added your own infrastructure.
How to measure your current count
A manual walk:
- Resolve
example.comTXT, find thev=spf1record. - For each mechanism, count it against the budget.
- For each
include:, resolve that domain's SPF and recurse.
Tools automate this — point one at your domain and it returns the total. If you are over ten, it returns permerror and lists which mechanisms pushed you over.
Three fixes
Fix 1: audit and remove. The highest-leverage fix is usually deletion. List every include: against actual sending traffic from the DMARC aggregate reports. A include: for a platform you stopped using a year ago still eats a lookup. Most domains can drop two or three mechanisms with no deliverability impact.
Fix 2: flatten. Replace include: chains with inline ip4:/ip6: ranges. The platform publishes its sending IPs; you pin them in your SPF. This works but breaks the day the platform changes their IP ranges without telling you. Only do this if you monitor a feed of changes or run an automated flattener on a cron.
Fix 3: DKIM-first alignment. DMARC only requires one of SPF or DKIM to pass with alignment. If all your important senders sign with DKIM using your domain, SPF failures for those same senders stop mattering. This is the modern approach: rely on DKIM for alignment and use SPF as a soft signal.
Flattening and DKIM-first each have trade-offs. The "permerror" state is always worse than either fix.
Check your SPF lookup count →
Further reading
- What is DMARC?
- Email deliverability checklist
- RFC 7208 — Sender Policy Framework (especially §4.6.4)