Skip to content

SPF too many DNS lookups: the 10-lookup limit and how to fix it

Breakage - SPF returns permerror and stops contributing to DMARC alignment

Critical / Warning
Breakage
Email Authentication
SPF

Critical

Evaluating your SPF record requires more DNS lookups than the specification allows, or the count is close enough that one provider-side change would push you over. Over 10 lookups, receivers must returnpermerror, which means SPF stops contributing to DMARC alignment.

The rule

RFC 7208 section 4.6.4 caps a single SPF evaluation at 10 terms that cause DNS queries. This is a MUST in the spec: past 10, an implementation is required to return permerror.

The limit exists for a specific reason. Without it, someone could publish a record full of references to a victim domain and then send mail to many receivers, each of which would dutifully resolve the whole chain. The receivers become an amplifier. Capping the work bounds that.

What counts, and what does not

Counts toward the limit: include, a, mx, ptr, exists, and the redirect modifier.

Does NOT count: ip4, ip6, all, the exp modifier, and the initial TXT query that finds your record.

The counter is global, not per record

This is the part that catches people. RFC 7208 section 4.1 is explicit that the 10-lookup limit is tracked as a single global limit across all evaluations, not per recursion. So when your record saysinclude:_spf.example.net, you spend one lookup on the include itself, and then every lookup-causing term inside that provider's record spends from the same budget. If their record includes two more records, those count too.

The practical consequence: your record can look small and still be over. Four or five includes is enough to blow the limit if the providers behind them have layered records of their own. It also means the count can change without you touching your DNS - a provider restructures their SPF, adds an include, and your record goes from nine lookups to eleven overnight.

Two sub-limits apply additionally: for mx, resolving each MX name must not require more than 10 address records - exceed that and the mx mechanism produces permerror. For ptr and the %{p} macro, if a PTR lookup yields more than 10 address records, everything after the first 10 is ignored (it truncates rather than errors).

What permerror actually costs you

The spec does not mandate what a receiver does with permerror. Handling is local policy, and it varies. Some accept and annotate. Some reject with a 550. Where it consistently hurts is DMARC: SPF returning permerror is not a pass, so SPF cannot contribute alignment. If DKIM is signing and aligned you may not notice. If you were relying on SPF for alignment on a given stream, that stream starts failing DMARC, and under a p=reject policy the mail goes away.

The failure mode is also uneven, which makes it hard to diagnose. Different receivers implement the limits with different levels of strictness, so you get reports of "some mail is bouncing" rather than a clean break.

How to fix it

  1. Remove what you no longer use. This is the safest cut and usually the largest. Includes for services that were decommissioned, trialled and dropped, or inherited from a previous team accumulate quietly. Every one you delete frees its own lookups plus everything nested inside it.
  2. Move stable senders to direct IPs. RFC 7208 section 10.1.2 gives a clear cost ordering: prefer ip4 and ip6 over a, and a over mx, unless the underlying hosts change often enough that the maintenance cost is worse.
  3. Cut redundancy. The RFC calls out v=spf1 ip4:192.0.2.0/24 mx -all as a wasteful record, because the mx mechanism is spending a lookup to authorize hosts theip4 range already covers.
  4. Ask providers for a consolidated include. Some publish several includes for different products where a single one covers them all.
  5. Split senders across subdomains. If you genuinely have more senders than 10 lookups can express, send marketing from mail.example.com and transactional fromnotify.example.com, each with its own SPF record and its own budget.
  6. Flattening, with eyes open. Replacing includes with the IPs they currently resolve to gets you under the limit immediately, but freezes someone else's infrastructure into your DNS. When they add sending IPs, your record does not know. If you flatten, you need a refresh process.

How this is rated

This is a breakage finding: over the limit, your own mail's SPF returnspermerror, so SPF stops contributing to DMARC alignment. DNSAudit rates more than 10 lookups Critical, and warns from 7 upward, because a record sitting at 8 or 9 today is one provider-side change away from failing with no action on your part. Exactly 10 is legal but leaves zero headroom, so it sits at the top of the warning band rather than in the clear.

How much a permerror costs depends on your DMARC posture. On a domain at p=quarantineor p=reject with a stream that relies on SPF for alignment, this is an active deliverability incident. Where DKIM is signing and aligned on every stream, the same permerror is quieter - but it is still worth fixing, because you do not control when a provider pushes you over the line.

Reference: RFC 7208 section 4.6.4 (DNS lookup limits), section 4.1 (global limit across recursion), section 10.1.2 (administrator considerations), section 11.1 (processing limits).