OneWebDesk

Fixing SPF 'Too Many DNS Lookups' (permerror)

Diagnose and fix SPF permerror caused by exceeding the 10 DNS-lookup limit via flattening.

If a recipient's logs show Received-SPF: permerror or the message "too many DNS lookups", it means that evaluating your SPF record required more DNS lookups than the limit of 10 set by RFC 7208. When this happens the receiving server treats the SPF result as a permanent error it cannot trust, and even legitimate mail can fail authentication as a result.

The tricky part is that the limit counts every nested include too. Your record may look short with just one or two include mechanisms, but if each of those points to a record containing more includes, the real total blows past 10 quickly. The fastest path is to first measure where you stand with the SPF lookup counter, then trim from there using the steps below.

What the 10-lookup limit is and why it exists

SPF reads your v=spf1 record to decide whether the sending IP is authorized. Some mechanisms need extra DNS queries to make that decision. RFC 7208 §4.6.4 caps the total number of lookup-causing mechanisms at 10. Without that cap, a malicious or misconfigured SPF record could force the receiver to perform dozens or hundreds of DNS queries, turning SPF into a DNS amplification vector.

The key nuance: the 10 counts the number of mechanisms that trigger a lookup, not the raw query count. One include:example.com costs 1, and if the record it points to contains its own include, a, or mx, those draw from the same budget of 10. Separately, mx and ptr can produce extra queries when they return many hosts — if an MX returns more than 10 hosts, that alone is a permerror.

Which mechanisms count (comparison)

Knowing exactly what does and does not draw from the budget is the heart of the diagnosis. Here is the breakdown.

Mechanism / modifierCounts toward 10?Notes
includeYes (most common cause)Lookups inside the referenced record are summed recursively
aYesResolves the domain's A/AAAA records
mxYes1 MX query plus one per returned host (over 10 hosts is an immediate permerror)
ptrYes (avoid using)Slow and unreliable; RFC recommends against it
existsYesOne macro-based A lookup
redirect=YesEvaluation moves to the target record and its lookups are added
ip4 / ip6NoIP is written inline, no DNS needed (the basis of flattening)
allNoTerminator like -all/~all, no lookup

How to count your own domain

Counting by hand means walking the record line by line and expanding every nested include — and provider records change often, so manual counts drift fast. The reliable approach is to let the SPF lookup counter expand all nested includes and return the total. If you want to see the raw published record first, check it with the SPF lookup tool.

Worked example: hitting 11 and getting permerror

Here is how a record that looks short can cross the limit. Say your domain publishes:

v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net include:mailgun.org a mx -all

  • include:_spf.google.com = 1, with 3 more includes inside → +3 (subtotal 4)
  • include:spf.protection.outlook.com = 1, with 1 include inside → +1 (subtotal 6)
  • include:sendgrid.net = 1 (subtotal 7)
  • include:mailgun.org = 1 (subtotal 8)
  • a = 1 (subtotal 9)
  • mx = 1 (subtotal 10)

That is exactly 10 so far — but if the Google include nests one more include (as it sometimes does), the total becomes 11 and you get a permerror. This is a common real-world story: reports of "SPF broke one day and we changed nothing" are usually because a provider grew the records inside its own include.

Three ways to get under the limit

  1. Remove unused includes. It is very common to find leftover includes for marketing or transactional services you cancelled long ago. Delete any provider you no longer actually send mail through — this is the lowest-risk way to recover headroom.
  2. SPF flattening. Resolve the IP ranges an include ultimately points to and write them directly as ip4:/ip6:. Because ip4/ip6 trigger no lookups, they cost nothing against the budget of 10. The trade-off is that if the provider changes its IPs you must update your record yourself, so flattening fits stable, self-managed infrastructure best.
  3. Consolidate senders. If multiple providers do the same job, merge them, and split sending responsibilities across subdomains (for example, marketing on m.example.com) so the include count is spread out. Each domain gets its own independent budget of 10.

Finally, a permerror is not just one broken line. DMARC passes only if SPF or DKIM aligns and passes — so when SPF collapses into permerror, any mail that DKIM does not cover can fail DMARC too and end up quarantined or bounced. After cleaning up SPF, review your policy and reporting (rua) with the DMARC record generator so you can catch regressions quickly.

Frequently asked questions

What exactly does the 10-lookup limit count?
It counts the number of lookup-causing mechanisms, not the raw query count. include, a, mx, ptr, exists, and redirect each cost 1, and lookups inside an include are summed recursively. ip4, ip6, and all trigger no DNS and do not count.
Why did permerror appear when I changed nothing?
Most likely an external provider you reference via include grew the number of includes inside its own SPF record. Because the limit sums nested lookups, a provider-side change alone can push your total past 10. Re-check the current total with an SPF lookup counter.
Is SPF flattening risky?
Pinning IPs as ip4/ip6 uses no lookup budget, but if a provider changes its sending IPs your record goes stale and legitimate mail can fail. Flattening is safest for stable self-managed infrastructure rather than large cloud providers, and you should monitor for IP changes.
Does permerror affect DMARC?
Yes. DMARC requires that SPF or DKIM align and pass. If SPF collapses into permerror, any message without an aligned DKIM signature can fail DMARC and be quarantined or rejected. Review your DMARC policy after fixing SPF.
Does adding many ip4 entries hit the limit?
No. ip4 and ip6 carry the IP inline and require no DNS lookup, so they do not count toward the limit of 10. You should still mind the 255-character record length limit and overall readability.

Tools to use with this guide