DEV Community

Cover image for SPF Too Many DNS Lookups: Fix the 10-Lookup Limit and permerror
Denys Button
Denys Button

Posted on

SPF Too Many DNS Lookups: Fix the 10-Lookup Limit and permerror

SPF "Too Many DNS Lookups": Diagnosing and Fixing permerror

You added one more include: to your SPF record — a new ESP, a new outreach tool, a new SaaS vendor that needs to send on your behalf — and now mail that used to pass is failing SPF entirely. This is one of the most common silent failures in email infrastructure, and it doesn't throw an obvious error in most sending dashboards. It just quietly starts failing authentication.

The 10-lookup limit, explained

RFC 7208 caps SPF evaluation at 10 DNS lookups per check. Not 10 include: mechanisms — 10 total lookups, counting every mechanism that requires its own DNS query: include, a, mx, ptr, exists, and any redirect. ip4/ip6 and plain all don't count, since they don't require a lookup.

Here's the part that catches people off guard: each include: can itself contain more include: statements, each triggering its own lookup. A record with five includes can easily blow past 10 once you follow the chain, because vendors like your ESP or CRM often nest their own third-party includes inside their SPF record.

When the limit is exceeded, the result isn't "SPF fails" — it's permerror, a permanent evaluation error. Receiving servers treat permerror inconsistently, but many treat it as equivalent to a fail, which tanks deliverability across every stream sharing that domain, not just the one from the new vendor you added.

How to check your current lookup count

  1. Pull the raw SPF record:
dig TXT yourdomain.com +short
Enter fullscreen mode Exit fullscreen mode
  1. For every include: in the record, resolve it and count its own lookups:
dig TXT _spf.vendor.com +short
Enter fullscreen mode Exit fullscreen mode
  1. Repeat recursively — an include can point to another include.
  2. Or skip the manual recursion and run the domain through MXToolbox's SPF record check, which walks the full chain and reports the total lookup count plus a flag if you're at or over the limit.

If you're at 8–10, you're one vendor addition away from permerror. Fix it now, not after it breaks.

Common causes of an oversized SPF record

  • Stacking multiple ESPs (e.g., your transactional provider, your marketing platform, and a cold outreach tool) each with their own nested includes
  • Legacy vendors left in the record long after you stopped using them
  • CRM or helpdesk tools that ask you to add their SPF include for "better deliverability" but rarely get removed when you churn
  • Copy-pasted SPF records from old documentation that include unnecessary a or mx mechanisms alongside include: chains

How to fix it: flatten, consolidate, or delegate

1. Remove dead vendors first. Before doing anything structural, audit every include: against your actual active sending tools. This alone often solves it.

2. Flatten static includes into IP ranges. If a vendor's sending IPs are stable, replace include:vendor.com with the resolved ip4: ranges directly in your record. This removes the lookup entirely, but you now own the maintenance burden if the vendor changes IPs — track their changelog or re-flatten periodically.

3. Consolidate under one subdomain per sending stream. Some senders split cold outreach, transactional, and marketing mail across subdomains (e.g., mail.yourdomain.com for outreach), each with a leaner, purpose-specific SPF record instead of one bloated record trying to authorize everything.

4. Use a macro/flattening service if the includes are volatile. Tools like dmarcian's SPF Surveyor visualize the full lookup tree and can help you decide what to flatten versus what to leave as a live include for vendors that rotate IPs frequently.

What the fixed record should look like

A lean, well-scoped SPF record for a domain sending through one ESP and one cold outreach platform might look like:

v=spf1 ip4:203.0.113.0/24 include:_spf.esp-example.com -all
Enter fullscreen mode Exit fullscreen mode

Note -all (hard fail) versus ~all (soft fail) — that's a separate decision from lookup count, but worth checking while you're in here. A record with ?all (neutral) provides essentially no protection and is worth tightening once your legitimate senders are fully accounted for.

Verification checklist

  1. Run MXToolbox SPF check — confirm lookup count is under 10, ideally under 8 to leave headroom.
  2. Confirm no permerror or temperror in the result.
  3. Remove any include: for vendors no longer in active use.
  4. Flatten stable, high-lookup includes to ip4:/ip6: where feasible.
  5. Re-check after any new vendor is added — this is a recurring maintenance task, not a one-time fix.

Don't stop at SPF

A passing SPF record doesn't guarantee inbox placement on its own — it needs to align with DKIM under DMARC, and it's just one layer of a much larger diagnostic. Vendors change IP ranges without much warning, so this is worth re-checking on a schedule, not just when something breaks.


For a full DNS-lookup audit workflow alongside DKIM and DMARC checks, the Cold Email Deliverability Kit (https://remixdenis.gumroad.com/l/kit) includes the exact diagnostic steps and a bounce-code cheat sheet for when authentication failures start showing up as bounces. The course Deliverability Diagnostics: What Actually Gets Email to the Inbox (https://remixdenis.gumroad.com/l/mclaie) covers flattening strategy and multi-vendor SPF architecture in more depth.

Top comments (1)

Collapse
 
md_pabel_fe07e07449db7326 profile image
MD Pabel •

The recursive includes are what make this problem easy to miss. Counting the full DNS chain is more useful than counting only the visible includes.