SPF PermError: too many DNS lookups — how to fix it

If a DMARC report or a bounce message mentions permerror or "too many DNS lookups," your SPF record has outgrown a hard limit written into the SPF standard: evaluating the record must not take more than 10 DNS lookups. Past that, receivers stop evaluating and return a permanent error — which most mailbox providers score the same as an SPF fail.

Updated July 13, 2026

Why the limit exists and what counts toward it

Every include:, a, mx, ptr, exists: and redirect= in your SPF record costs one DNS lookup — and the includes of your includes count too, recursively. ip4:, ip6: and all are free. The limit exists so a single email can't trigger unbounded DNS traffic (RFC 7208 §4.6.4).

The trap is that you don't control the recursion: include:_spf.example-esp.com might itself contain three more includes today and five next quarter. Records drift over the limit without anyone touching them.

Step 1 — count your actual lookups

Run your domain through our SPF checker — it resolves the whole include tree and shows the exact lookup count against the limit of 10, with each include's contribution broken out.

Step 2 — remove what doesn't belong

  • Services you stopped using. Old ESPs, a former helpdesk, a marketing tool from two contracts ago — every abandoned include is wasted budget.
  • ptr mechanisms — deprecated, slow, and each one costs a lookup. Nothing should still use them.
  • Duplicate coverage: if a vendor's include already authorizes a range you also list as a or mx, drop the redundant mechanism.
  • mx when your mail servers never send outbound from those IPs (common with hosted mailbox providers — their include already covers sending).

Step 3 — flatten what's left, carefully

Flattening replaces an include: with the literal ip4:/ip6: ranges it currently resolves to — zero lookups. Our SPF flattener does this for you. The trade-off: when the vendor changes their IPs, a flattened record goes stale silently. Flatten the stable entries (your own infrastructure), keep live includes for big ESPs that rotate ranges, and re-check monthly — or let monitoring re-check daily for you.

v=spf1 include:_spf.google.com include:old-esp.example include:mx.example ptr a mx ip4:203.0.113.10 ~all

v=spf1 include:_spf.google.com ip4:198.51.100.0/24 ip4:203.0.113.10 ~all
Before (12 lookups) → after (4 lookups)

If you still can't get under 10

Split senders across subdomains. Marketing mail from news.yourdomain.com gets its own SPF record with its own 10-lookup budget, and your root record shrinks. This is good practice anyway: it isolates each sender's reputation, and DMARC still protects everything.

Common questions

Does a PermError mean my email stops delivering?+

Not by itself — but under DMARC, a PermError means SPF can't contribute a pass, so authentication rests entirely on DKIM. If DKIM also fails or isn't aligned, your mail fails DMARC and gets quarantined or rejected depending on your policy. It's a single point of failure you want gone.

Do nested includes really count against my limit?+

Yes. The 10-lookup budget covers the entire evaluation, recursively. One include that internally fans out to four more lookups costs you five.

Is flattening safe?+

Safe to do, risky to forget. The flattened IPs are correct the day you publish them; vendors then change ranges without telling you. Flatten stable sources, keep includes for ESPs, and re-verify the record on a schedule.

Does the 10-lookup limit apply to ip4/ip6 entries?+

No — literal IP mechanisms and the final `all` cost nothing. That's exactly why flattening works.