Sender Policy Framework (SPF) is a small but strict protocol. One of its least-forgiving rules is a cap on how many DNS queries a single SPF evaluation may perform. Cross that line and receiving mail servers stop evaluating your record and return a permerror — a permanent error that, in practice, means SPF simply fails.
This guide explains the rule, shows you how to count your own lookups, and walks through the durable ways to bring a bloated record back under the limit.
For the site owner (plain English)
This means your SPF record — the DNS line that lists who may send email for your domain — has grown too big and now trips a hidden limit, which can quietly send your real mail to spam. It is worth fixing, though it is not a same-day emergency. The usual cause is simple: over the years you added a line for each new tool (a newsletter service, a CRM, a support desk) and the list eventually crossed a ten-lookup ceiling built into the standard. The fix is to trim that one TXT record: log in to your DNS provider, remove entries for tools you no longer use, and where possible replace a provider's include: with its fixed IP addresses, which do not count against the limit. It is editing a single record, not rebuilding your email.
What is the SPF 10-lookup limit?
SPF is defined by RFC 7208. Section 4.6.4 sets a hard ceiling: during a single check of your SPF policy, a receiver may perform at most ten DNS lookups for mechanisms and modifiers that require DNS resolution.
The intent is to protect mail servers from being used to amplify denial-of-service traffic — without a cap, a maliciously nested SPF record could trigger an unbounded cascade of queries. When the eleventh lookup is reached, the evaluation halts and the result is permerror.
The catch is that the limit counts lookups, not the number of characters or terms in your published record. The mechanisms that each consume one or more lookups are:
include— eachinclude:term costs one lookup, plus every lookup performed by the included record (nesting is recursive).a— resolving the A/AAAA records of a name costs one lookup.mx— costs one lookup to fetch the MX records, and the subsequent A/AAAA resolution of each returned host can add more.ptr— costs one lookup. It is also discouraged by RFC 7208 and should be avoided entirely.exists— costs one lookup.- The
redirectmodifier — counts toward the limit as well.
Crucially, ip4: and ip6: mechanisms cost zero lookups, because the address is already in the record and no DNS query is needed to resolve it. The same is true for all. This is the lever that almost every fix relies on.
Why nesting is the usual culprit
A single include:_spf.google.com looks like one lookup, but Google's record itself contains further includes, each resolving to more. A record that publishes only three or four includes can quietly resolve to twelve or thirteen lookups once every nested level is followed. Because the bloat lives in records you do not control, the count can also drift over time as those providers restructure their own SPF.
What permerror does under DMARC
On its own, an SPF permerror means the SPF check yields no useful pass. Under DMARC, alignment depends on SPF (or DKIM) producing a pass that aligns with the visible From domain. If SPF permerrors and DKIM is absent or also fails, DMARC fails — and ap=reject or p=quarantine policy will then have your legitimate mail rejected or sent to spam. A lookup overflow is therefore not a cosmetic warning; it can silently break deliverability.
How do I count my own lookups?
Counting by hand means walking the record depth-first. Start at your published v=spf1 record, add one for each lookup-consuming mechanism, then recurse into every include and redirect and add their lookups too. Continue until you have expanded every branch.
v=spf1 include:_spf.google.com include:servers.mcsv.net include:sendgrid.net a:mail.example.com -allIn the example above you can already see four lookup-consuming terms at the top level (three includes plus one a). But each of those includes expands further — _spf.google.com alone typically adds three nested includes — so the true total is what matters, not the four terms you can see.
Rather than tracing this manually every time, use a checker. An SPF validation tool will expand the full tree, show the running count, and flag exactly which branch pushes you over ten. Our DMARC and email authentication checker does this expansion for you and reports the lookup total alongside any permerror risk.
How to fix it
There is no way to raise the limit — receivers enforce it, not you — so every fix reduces the number of lookups your record requires. Work through these in order; the early steps are the safest.
1. Remove dead includes
Most overflowing records carry includes for services that are no longer sending mail: a retired marketing platform, a help-desk tool you migrated away from, a one-off campaign vendor. Every stale include wastes at least one lookup, often several once nested. Audit each include against the systems that actually send as your domain today, and delete anything you cannot account for. This is the single highest-value step and carries almost no risk, because you are only removing authorization for senders that no longer exist.
2. Replace includes with ip4/ip6 for stable senders
If a sender publishes a small, stable set of sending IP addresses, you can list those addresses directly with ip4: / ip6: instead of including the provider's record. Because IP mechanisms cost zero lookups, this can reclaim several lookups at once.
# Before (1+ lookups, possibly nested):
include:mail.vendor.example
# After (0 lookups):
ip4:198.51.100.0/24 ip6:2001:db8:abcd::/48Only do this for providers whose ranges genuinely do not change — your own outbound relay, a fixed transactional gateway, a colocated server. For large cloud senders whose ranges shift, keep the include (see the gotcha below).
3. Drop redundant a and mx mechanisms
Many records inherit an a or mx mechanism that was added "just in case." If your domain's A record or mail exchangers do not actually send outbound mail, those mechanisms are pure cost. Remove them. Where they are needed and the addresses are stable, replace them with explicit ip4:/ip6: entries to convert a lookup into a zero-cost term.
4. Consolidate or flatten the record
If you still exceed ten after pruning, consolidation is the next tool. Flattening means resolving every include down to the underlying IP addresses and publishing those addresses directly, so the receiver performs no nested lookups at all. Done well, a flattened record can sit comfortably at zero or one lookup regardless of how many providers you use.
The right way to flatten is with a maintained flattening service that re-resolves your providers' records on a schedule and updates the published IPs for you (often by hosting the record at a delegated subdomain you include or redirect to). That keeps the convenience of a flat record without the maintenance trap of a static snapshot. The caveat is real and is covered next.
include for any provider whose IP ranges are volatile.How do I verify the fix?
After every change, confirm two things: that the published record parses as a single valid v=spf1 policy, and that its fully expanded lookup count is ten or fewer. DNS caching means an edit can take time to propagate, so re-check after the TTL has elapsed rather than immediately.
- Run an SPF lookup-count check and confirm the total is ≤ 10 with no
permerror. - Send a test message to an address that reports authentication results and confirm SPF shows
passfor your sending IP. - Check your DMARC aggregate reports over the following days to confirm SPF is passing and aligned across all your real senders.
See your fully expanded SPF lookup count and permerror risk in seconds.
Check your SPF record →For the full picture of how SPF, DKIM, and DMARC fit together, read the email authentication guide. If your domain has accidentally published more than one SPF record — another common cause of permerror — see how to fix multiple SPF records. For step-by-step DNS entry, see setting up SPF, DKIM and DMARC on GoDaddy, and for the bigger picture read how to prevent email spoofing of your domain.