Skip to content
Authentication

The SPF 10 DNS lookup limit

SPF evaluation stops after 10 DNS lookups and returns permerror. Which mechanisms count, how includes multiply the cost, and the fixes that keep records under budget.

SPF evaluation is capped at 10 DNS lookups per check. The mechanisms include, a, mx, ptr, and exists, plus the redirect modifier, each consume one or more lookups, counted recursively through every included record. When an evaluation would need an eleventh lookup, the receiver stops and returns permerror, a permanent error that makes the record useless everywhere at once. This limit, defined in RFC 7208 to prevent SPF from being abused for DNS amplification, is the most common way otherwise correct SPF records break.

What counts and what does not

Counting toward the limit: every include, a, mx, ptr, and exists mechanism, and the redirect modifier. Free: ip4, ip6, all, and the initial fetch of the record itself. The mx mechanism carries a second cost layer: resolving each MX hostname to addresses, capped at 10 per mx term. There is also a separate cap of 2 void lookups, queries that return no answer, so dead hostnames in a record can trigger permerror even under the main budget.

Why records go over: recursive counting

An include costs one lookup plus everything the included record spends internally, and vendor records nest. include:_spf.google.com expands to three further includes, four lookups total. A record with four popular SaaS vendors can quietly evaluate to twelve lookups while containing only four visible terms. Vendors also change their records without notice, which means your record's lookup count changes without any edit on your side. Records that passed for years fail one Tuesday because a vendor restructured.

Four terms, over budgetRFC 1035
TXT / SPFMX / PTRA / AAAACNAME / NS / other
"v=spf1 include:_spf.google.com include:sendgrid.net
include:mailgun.orgMX-all"
include:_spf.google.com 4 lookups (1 + 3 nested)
include:sendgrid.net 1 lookup
include:mailgun.org 2 lookups (1 + 1 nested)
MX1 + one per MX host (e.g. 3 total)
------
10+ lookups: permerror territory

What permerror costs

Permerror is not a partial result: the entire record is discarded, as if the domain published broken SPF, because it did. Under DMARC, SPF then contributes nothing, and authentication rests entirely on DKIM alignment. Domains with healthy aligned DKIM survive with an invisible degradation; domains relying on SPF for DMARC start failing DMARC outright, and at p=quarantine or p=reject their mail stops arriving. The failure is global and simultaneous at every receiver, which is also the diagnostic tell.

Getting back under budget

Fixes in order of preference

  1. 1

    Delete dead weight

    Cross-reference every include against actual sending sources in DMARC reports. Retired vendors, unused tools, and mx mechanisms on domains whose MX hosts never send outbound all come out. This alone fixes most over-limit records.

  2. 2

    Split streams across subdomains

    Give each sending stream its own subdomain with its own small record: the ESP include lives at news.example.com, the billing tool at billing.example.com. Each record stays trivially under budget.

  3. 3

    Replace stable vendors with ip4 ranges

    Where a vendor publishes stable, documented IP ranges, literal ip4 mechanisms cost zero lookups. Only do this with ranges the vendor commits to, and note the maintenance obligation.

  4. 4

    Automated flattening, as a managed dependency

    Flattening services resolve your includes to IP lists and republish your record continuously. It works, and it means a third party edits your DNS forever. Manual one-time flattening is a time bomb and not a fix.

The strategic fix is reducing what SPF has to carry. DMARC needs one aligned mechanism per message, and DKIM alignment survives forwarding, vendor changes, and the lookup budget entirely. A sender whose every stream signs with aligned DKIM can treat SPF as supporting evidence rather than a single point of failure, which shrinks both the record and the stakes.

Checking your count

Online counters (the dmarcian SPF Surveyor, MxToolbox, and most DMARC platforms) resolve the full include tree and report the effective lookup total on demand. Treat 8 as the practical ceiling, leaving headroom for vendor drift, and re-check whenever a vendor is added and on a schedule. Validation tooling and the wider failure vocabulary are covered in the testing and troubleshooting entry.

Frequently asked questions

Do ip4 and ip6 mechanisms count toward the 10?
No. Literal IP mechanisms and the all terminator are free, which is why flattening and subdomain splitting work as fixes.
My checker says 9 lookups. Am I safe?
For today. Vendor records change without notice, and one internal restructure can push you over. Keep records at 8 or fewer and monitor, rather than parking at the cliff edge.
Does the limit apply per receiver or globally?
Per evaluation, identically at every RFC-compliant receiver. That is why exceeding it fails everywhere simultaneously rather than at one provider.
Is the limit changing in newer standards?
No relief is coming; the cap exists for abuse prevention and remains in current specifications. Plan record architecture around it as a permanent constraint.

Key takeaways

  • SPF evaluation aborts with permerror after 10 DNS-querying mechanisms, counted recursively through includes
  • Vendor includes cost whatever their nested records spend, and vendors change them without telling you
  • Permerror discards the whole record everywhere at once, leaving DMARC to rely on DKIM alone
  • Fix order: remove unused includes, split streams across subdomains, use literal IPs for stable ranges, treat flattening services as a permanent dependency
  • Watch for spf=permerror in DMARC reports and keep effective counts at 8 or below for drift headroom