SPF: too many DNS lookups

SPF evaluation is allowed ten DNS-querying terms. Your record needs more, so an evaluator stops and returns permerror — the same outcome as a malformed record, which means SPF contributes nothing and DMARC loses one of its two paths. This page shows which terms count, how to count them through nested includes, and how to get under the limit without silently cutting off a sender.

Measured 2026-09-08: 13 of 320 audited domains (4.06%) exceeded the ten DNS-lookup limit. These are domains someone had a reason to check, so this is an upper bound and not an internet-wide rate — method, window and exclusions in SPF Observatory 2026.

What was observed

Counting every include, a, mx, ptr, exists and redirect reached through your record, including the ones inside other people's includes, the total exceeds 10.

What causes it

These are protocol and measurement causes only. We do not speculate about what a receiver did with the result.

How to verify it yourself

  1. Read the record
    dig +short TXT example.com | grep spf1
  2. Resolve one include to see what it costs
    dig +short TXT _spf.google.com

Check this record Reads the live record and counts every DNS lookup it costs.

The safe fix, and what it can break

Remove vendors you no longer send through — that is the only change with no downside. Then replace a and mx with the ip4 literals they resolve to, if those addresses are stable. Only then consider flattening, and read the warning below before you do.

What can break: Flattening replaces an include with the addresses it resolves to today. When the vendor changes its addresses, your record still names the old ones and their mail starts failing — with no error anywhere, because the record is still syntactically valid. If you flatten, you now own a maintenance job you did not have before.

Examples

Eleven lookups — over the limit
v=spf1 include:_spf.google.com include:mail.zendesk.com include:servers.mcsv.net include:spf.protection.outlook.com include:spf.mandrillapp.com include:spf.mtasv.net a mx a:smtp.example.com a:bulk.example.com exists:%{i}._spf.example.com ~all
The same six senders, six lookups
v=spf1 include:_spf.google.com include:mail.zendesk.com include:servers.mcsv.net include:spf.protection.outlook.com include:spf.mandrillapp.com include:spf.mtasv.net ip4:203.0.113.10 ip4:203.0.113.11 ip4:203.0.113.12 ~all

The six vendor includes are untouched. What went is the five terms that queried your own DNS — a, mx, two a: hosts and an exists: — replaced by the three addresses they resolve to. Every term above is countable from the record text itself: eleven DNS-querying terms in the first, six in the second. Counted against the live records on 2026-09-08; a vendor that later nests an include inside its own record adds to these totals, which is the direction that breaks a record rather than fixes it.

What the standard says

RFC 7208 §4.6.4: “If this limit is exceeded, the implementation MUST return "permerror"”

What is the SPF 10 DNS lookup limit?

RFC 7208 §4.6.4 caps DNS-querying terms at ten per evaluation. Exceeding it is not a warning: “If this limit is exceeded, the implementation MUST return "permerror"”.

Which mechanisms count as lookups and which do not?

Counting: include, a, mx, ptr, exists, and the redirect modifier. Not counting: ip4, ip6, all.

Why does exceeding it return PermError?

Because the evaluator stops before reaching a verdict. A permerror means the record “could not be correctly interpreted” (§2.6.7), so SPF contributes nothing rather than failing.

How do I count lookups across nested includes?

Every include costs one, plus everything inside it, recursively. A vendor whose record contains three includes costs you four, not one. Resolve each with dig and add them up, or use the checker, which does it for you.

Which includes cost the most?

The ones that nest. Large ESPs often split their ranges across several sub-includes, so a single line in your record can account for four or five of your ten.

How do I reduce lookups without breaking a sender?

Remove vendors you no longer use first — that is the only free change. Then replace a and mx with the literals they resolve to, if stable. Verify with DMARC reports before tightening further.

Is SPF flattening a safe fix?

Not on its own. It converts a vendor's include into today's IP list, so it goes stale silently when the vendor renumbers. Nothing errors; their mail just starts failing. Treat it as taking on maintenance, not removing it.

What is the void lookup limit?

Separate from the ten. RFC 7208 §4.6.4 also limits lookups that return no records; two is the recommended maximum, and exceeding it is also a permerror. Typos in include targets are the usual cause.

Does the limit apply per include or in total?

In total, across the whole evaluation including everything reached through nested includes. It is not ten per include.

What we do not claim

We report what your DNS publishes and what an evaluator would return from it. We do not state what any mailbox provider will do with that result: those decisions are theirs, they are not published, and we cannot measure them from here.

Reviewed by Venkat Nookala, last reviewed 2026-09-08.