Cybersecurity

SPF 10 DNS Lookup Limit: How to Avoid Exceeding It

Understand why SPF limits DNS lookups to 10, how nested includes count recursively, and strategies to stay under the limit.

By Inventive HQ Team

The SPF specification (RFC 7208, Section 4.6.4) requires every receiving mail server to abort SPF evaluation after 10 DNS-querying mechanisms — the include, a, mx, ptr, and exists mechanisms and the redirect modifier each cost exactly one lookup, while all, ip4, and ip6 cost nothing. Nested includes are counted recursively, so a single include:_spf.vendor.com that itself contains three includes adds four lookups to your total, not one. Cross the limit and SPF returns a permerror, which is not a pass — so DMARC treats the message as SPF-unaligned, and a strict p=reject policy can start bouncing legitimate mail from an entire sending source.

That is the summary an AI Overview will give you. What it cannot show you is where your lookups actually go — the recursive fan-out hidden inside common vendor includes, the exact result codes a receiver returns, and the order in which you should attack an over-limit record. Below is an animated map of how one include explodes into many lookups, a table of every mechanism's cost, a symptom-to-fix troubleshooting guide, and a repeatable remediation checklist.

Why the limit exists

The cap is a denial-of-service protection. Because include and redirect chain to other domains' SPF records, an attacker (or an accident) could craft records that force a receiving server to perform thousands of recursive DNS queries per inbound message — an amplification vector. RFC 7208 draws a hard line at 10 to keep the cost of validating any single message bounded. It is not a suggestion or a soft warning: a compliant evaluator must return permerror the moment the eleventh DNS-querying term is reached.

How one include becomes many lookups

The trap is that the count is recursive. You write one include: and feel like you spent one lookup, but the vendor's record includes their upstream providers, which include theirs. Here is how a typical record fans out.

Recursive SPF include expansion counting toward the 10-lookup limit A root SPF record with three includes; one vendor include expands into three nested includes, showing how the lookup count climbs from 3 to 7. One include is rarely one lookup Each box is a DNS-querying term. The counter climbs as the receiver walks the tree. v=spf1 (your domain) 3 includes + ~all include:spf.google.com include:_spf.vendor.com include:mailgun.org include:sendgrid.net include:amazonses.com a / mx terms Running lookup count 3 7 3 top level → fully expanded

The three top-level includes look cheap, but expanding just the vendor include pulls in SendGrid, Amazon SES, and its own a/mx terms. A record that reads like "three includes" resolves to seven or more lookups — and you are two vendor additions away from a permerror.

Advertisement

Cost of every SPF term

Not every mechanism is created equal. This is the complete cost table for the limit of 10.

TermCosts a lookup?Notes
include:Yes (1)Counted recursively — nested includes add up
redirect=Yes (1)Modifier; replaces the record, still costs a lookup
aYes (1)Resolving the A/AAAA of the named host
mxYes (1)Plus a sub-limit: max 10 address records per mx
ptrYes (1)Discouraged by RFC 7208 — slow and unreliable, avoid it
existsYes (1)Used in macros; each evaluation is one lookup
ip4NoLiteral address range — the cheapest way to authorize senders
ip6NoLiteral address range — free
allNoThe terminator (-all, ~all, ?all); never a lookup

Which should you reach for when trimming? Convert the includes you can pin to stable IP ranges into ip4/ip6 (free), delete unused vendor includes entirely, and never use ptr — it is the mechanism RFC 7208 explicitly tells you to avoid.

The other limit nobody remembers: void lookups

Even under 10 total lookups, SPF can still permerror. RFC 7208 sets a separate recommended cap of 2 void lookups — DNS queries that return NXDOMAIN or an empty answer. A stale include: pointing at a decommissioned vendor hostname burns a void lookup every time. Two of those and evaluation fails regardless of your total count. When you audit, resolve every hostname in the chain and delete anything that no longer answers.

Symptom to cause to fix

When SPF breaks, the receiver's result code tells you exactly which limit you hit.

Symptom / resultLikely causeFix
permerror in Authentication-ResultsMore than 10 DNS-querying termsCount and trim includes; flatten stable ones to ip4
permerror, but count looks under 10More than 2 void lookups (dead hostnames)Resolve every include; delete NXDOMAIN entries
SPF fails only for one vendorThat vendor's mx returns >10 address recordsReplace mx with explicit ip4 for that sender
DMARC fails despite "valid" SPFpermerror is not a pass — no alignmentGet under the limit; SPF must return pass
Intermittent failures after adding a vendorNew include pushed nested total over 10Move that sender to a subdomain SPF record
-all bouncing legitimate mailOver-limit permerror treated as fail by receiverRemediate lookups before tightening to -all

Remediation checklist

Work this list top to bottom; re-count after every step.

  1. Expand and count. Use our SPF generator or an SPF checker to recursively expand every include and get your true lookup total.
  2. Delete dead weight. Remove includes for vendors you no longer send through. This is usually the single biggest win.
  3. Resolve every hostname. Kill any include that returns NXDOMAIN — those are void lookups waiting to permerror.
  4. Consolidate senders. Fewer email vendors means fewer includes. Route transactional and marketing mail through the same provider where possible.
  5. Subdomain your bulk mail. Give newsletters and app notifications their own subdomain (e.g. mail.example.com) with a separate SPF record. Each record gets its own budget of 10.
  6. Flatten the stable includes. Replace includes whose IPs rarely change with literal ip4/ip6 ranges — but only with automation that re-resolves and updates on a schedule, or the record goes stale silently.
  7. Re-count and monitor. Confirm you are under 10, then watch DMARC aggregate reports for spf=permerror so a future vendor addition can't quietly break you.

Key takeaways

  • The limit is 10 DNS-querying terms, counted recursively across all nested includes, defined in RFC 7208 Section 4.6.4.
  • include, redirect, a, mx, ptr, and exists cost one lookup each; ip4, ip6, and all cost nothing.
  • Exceeding the limit yields a permerror, which is not an SPF pass and therefore breaks DMARC alignment.
  • A separate 2-void-lookup cap means dead hostnames can permerror you even under 10.
  • Flattening to literal IPs eliminates lookups but trades away automatic maintenance — use tooling, not a one-time manual edit.

Ready to count your real lookup total? Run your domain through our free SPF generator to expand every include and see exactly where your ten lookups go.

Frequently Asked Questions

What is the SPF 10 DNS lookup limit?

RFC 7208 requires SPF evaluators to abort after 10 DNS-querying terms. The mechanisms include, a, mx, ptr, and exists, plus the redirect modifier, each count as one lookup. Exceeding 10 produces a permerror, which causes SPF to fail and typically breaks DMARC alignment for that message.

Which SPF mechanisms count against the 10-lookup limit?

include, a, mx, ptr, exists, and the redirect modifier each cost one DNS lookup. The all, ip4, and ip6 mechanisms cost nothing because they require no DNS query. Nested includes are counted recursively, so an include that itself contains three includes adds four lookups, not one.

What happens when SPF exceeds 10 DNS lookups?

SPF evaluation returns permerror (permanent error). Under RFC 7208 a permerror is not a pass, so DMARC treats the message as SPF-unaligned. If DKIM also fails or is unaligned, a p=reject DMARC policy will bounce or quarantine legitimate mail. Many operators never notice until a whole sending source starts failing.

How do I check how many DNS lookups my SPF record uses?

Use an SPF checker or our SPF generator to expand every include recursively and count the DNS-querying terms. Manually, resolve each include, a, mx, ptr, and exists in the chain and add them up. Do this whenever you add a new email vendor, because each new include often brings several nested lookups with it.

What is SPF flattening and should I use it?

SPF flattening replaces include mechanisms with the literal ip4 and ip6 ranges they resolve to, dropping the lookup count to near zero. The tradeoff is maintenance: if a provider changes its sending IPs, your flattened record silently goes stale and mail fails. Only flatten with automated tooling that re-resolves and updates the record on a schedule.

Do ip4 and ip6 mechanisms count toward the SPF limit?

No. ip4, ip6, and all require no DNS query, so they never count against the 10-lookup limit. This is exactly why flattening includes into literal IP ranges eliminates lookup pressure, at the cost of manual maintenance when those ranges change.

How many void DNS lookups does SPF allow?

RFC 7208 recommends a separate limit of 2 void lookups, meaning DNS queries that return NXDOMAIN or an empty answer. Exceeding two void lookups also produces a permerror, so stale includes that point at dead hostnames can break SPF even when you are under 10 total lookups.

Does the mx mechanism count as one lookup or many?

The mx mechanism itself counts as one lookup against the limit of 10. However, RFC 7208 imposes a sub-limit: resolving a single mx term must not require more than 10 address-record queries, or evaluation fails. A domain with many MX hosts can trip this even though mx counts as one.

How do I fix an SPF record that exceeds 10 lookups?

Audit every include and remove vendors you no longer use, consolidate senders onto fewer providers, move bulk mail to a subdomain with its own SPF record, replace some includes with static ip4 ranges, and consider automated flattening for the noisiest includes. Re-count after every change to confirm you are back under 10.

SPFDNS lookupsemail authenticationSPF optimization