SPF PermError: Too Many DNS Lookups
An SPF record can be syntactically perfect and still fail every message because evaluating it costs too many DNS queries. This guide explains where the limits come from and how to get back under them safely.
Why SPF has lookup limits
SPF is evaluated by the receiving server while a message is arriving, using DNS queries it makes on behalf of the sender's domain. Because a domain owner controls the record, an unbounded record could make receivers do arbitrary amounts of work, or be used to aim large numbers of queries at a victim. RFC 7208 section 4.6.4 therefore limits an evaluation to 10 terms that cause DNS queries and also limits lookups that return nothing.
Only some terms spend a lookup. The mechanisms include, a, mx, ptr and exists, and the redirect modifier, count. The mechanisms ip4, ip6 and all, and the exp modifier, do not. Counting is cumulative through nested records, so an include of a provider that itself includes three others costs four lookups, not one.
PermError, TempError and the other results
SPF evaluation ends in one of seven results: none, neutral, pass, fail, softfail, temperror and permerror. The two error results are easy to confuse. A temperror means a transient condition, normally a DNS timeout or server failure, while fetching a record. The receiver may retry or defer, and the same message can pass later. A permerror means the record cannot be evaluated no matter how often it is retried: more than one SPF record at the name, a syntax error, an include loop, or exceeding the lookup limits.
What the receiver then does with a permerror is its own policy. Some reject, some treat it like a failure, some ignore it. Under DMARC, SPF contributes nothing to a permerror message, so alignment must come from DKIM. A domain with a broken SPF record and fragile DKIM is therefore exposed in ways that are difficult to notice from the sender's side.
Void lookups
A void lookup is a DNS query made while evaluating the record that returns NXDOMAIN or an answer with no records. RFC 7208 recommends that evaluation stop with permerror after two of them. They usually come from include targets that no longer exist, a mistyped domain, or an a or mx term for a name with no matching records. A record under 10 lookups can still fail because of two dead includes. The SPF checker counts both numbers separately.
Finding where the lookups go
- Run the SPF checker on the sending domain and note the total and the contribution of each top-level term.
- List which terms are includes for third-party services, and which services you still use. Any service that has been retired is a pure saving.
- Look for
aandmxterms. Each is a lookup, andmxadditionally causes address lookups for each MX name that are not included in this tally by the tool. - Check for
ptr, which should not be used at all, and forexistsmacros that were added for a specific purpose. - Check subdomains. A service that sends from a subdomain can have its own SPF record there instead of being added to the main domain.
Reducing lookups safely
The options range from low risk to high risk. Removing include terms for services you no longer use is the safest: confirm in DMARC reports that nothing is still sending through them first. Splitting traffic is next: give a marketing platform its own subdomain such as news.example.com with its own SPF record, so that the sums do not accumulate at the apex. Replacing an include with fixed ip4 or ip6 ranges costs no lookups, but only do it for ranges that you control or that the provider commits to keep stable, because a provider can change addresses without telling you and your mail will silently begin to fail.
Automated 'flattening' services convert includes into address lists and refresh them on a schedule. They can work, but they move a dependency into your DNS: if the refresh stops, the record goes stale. Treat them as an operational process with monitoring, not a one-off fix. The record also has a size limit in practice. Long records with many addresses can exceed what fits in a single DNS response, so check the final length.
Rolling the change out and rolling it back
Save the current record text before editing so that rollback is a paste. Make one change, publish, wait for the TTL, run the check and send a test message to an outside mailbox, then read the received headers for spf=pass. If anything starts failing, restore the saved record. Keep exactly one v=spf1 record at each name throughout, because two records are themselves a permerror. Combine changes to SPF with a look at DMARC aggregate reports for a few days afterwards, which will show any sender you overlooked.
Frequently confused points
Passing the lookup limit does not mean the mail passes SPF; it only means the record can be evaluated. SPF also checks the envelope sender, not the From header, so a message may pass SPF yet fail DMARC alignment. And a DNS error during the check is not evidence of a missing record: the SPF checker reports such cases as unknown.
Frequently asked questions
Is the limit 10 lookups or 10 includes?
Ten DNS-querying terms in total, counted through all nested records. Includes are only one kind of term that counts.
Does ip4 count toward the limit?
No. ip4, ip6 and all do not cause DNS queries and are not counted.
Will every receiver reject mail on permerror?
No. The handling is up to each receiver. Do not rely on lenient handling.
Should I use SPF flattening?
Only with monitoring. A flattened record can go stale if a provider changes addresses and the refresh process stops.
Written by DNS Tools editorial · Last updated 2026-10-09