Email authentication · Practical guide

SPF permerror: trace too many DNS lookups before editing records

Count the DNS-triggering terms evaluated along the sending path, including nested includes. Counting only the includes visible in your top-level record can miss the cause of an SPF lookup-limit error.

Reviewed · Examples are illustrative

Who this helps: Mailbox and domain administrators investigating an SPF permerror.

Confirm the error before choosing a fix

SPF permerror is a permanent evaluation error, not a synonym for too many lookups. Multiple SPF records and invalid syntax can also cause it. A transient DNS failure can instead produce temperror. Preserve the receiver's exact diagnostic and identify the envelope-sender domain being checked before editing anything.

  1. Save a redacted message result with its time and sending service.
  2. Confirm which domain was evaluated; do not assume it was the visible From domain.
  3. Retrieve the current SPF TXT record and any referenced records. Save that snapshot for comparison.
  4. If the error explicitly reports a lookup limit, trace the evaluated terms. If it reports syntax or duplicate records, investigate that cause first.

Source: RFC 7208: SPF evaluation and DNS lookup limits, section 4.6.4

What consumes the lookup budget?

RFC 7208 limits DNS-triggering terms during evaluation to ten. These include include, a, mx, ptr, exists and redirect, including nested evaluation. The ip4, ip6 and all mechanisms do not consume that term budget. Additional limits apply to MX/PTR processing and void lookups; ‘ten DNS packets’ is not an accurate implementation rule.

Evaluation follows the record's logic and can finish before reaching later terms. Diagnose the affected sender path rather than claiming a simple text count predicts every result.

Source: RFC 7208: SPF evaluation and DNS lookup limits, section 4.6.4

Worked example: an include chain hides the extra work

This deliberately simplified fixture uses reserved example domains and a documentation IP address. It is for reasoning about the evaluation path, not a record to publish. Suppose the sending IP does not match until the deepest record. Each record from r1 through r10 contains only the next include followed by -all; r11 contains the final address mechanism.

The useful lesson is the shape of the investigation: expand dependencies and keep a running trace. A real provider may have branches, different mechanisms and records that change over time. Preserve the actual snapshot and use a standards-aware evaluator rather than treating this teaching fixture as a complete SPF validator.

example.com: v=spf1 include:r1.example -all
r1.example:  v=spf1 include:r2.example -all
...
r10.example: v=spf1 include:r11.example -all
r11.example: v=spf1 ip4:192.0.2.10 -all
Evaluation pointCumulative include termsWhat it tells you
example.com → r11Only one include is visible in the top-level record
r1 → r22The referenced record adds work
r9 → r1010The term budget has been consumed
r10 → r1111Evaluation exceeds the limit before reaching the final address

Reduce unnecessary dependencies without breaking another sender

Build an inventory of every service authorized by the record. Ask its owner whether it still sends mail, whether the include is still recommended by that provider, and whether an old migration left a redundant entry. Removing a retired dependency is easier to justify when you have an owner and a test plan.

For a hypothetical company with a retired newsletter service, the change proposal should name that service, explain why it is no longer needed, show the record before and after, and list the remaining services to test. Do not remove a service simply because you have not personally used it. Password resets, invoices and support mail may be owned by another team.

Avoid manually replacing a provider's maintained include with a snapshot of its IP addresses without an explicit maintenance arrangement. An address list that works today can become stale. Also avoid publishing a second SPF record as a workaround; it does not provide another budget.

  1. Save the existing record and the evidence supporting the proposed change.
  2. Have the domain owner review the replacement and its effect on each legitimate sender.
  3. Apply the smallest justified change through the domain's normal change process.
  4. After DNS caches have refreshed, evaluate each sending service again and inspect fresh received messages.
  5. If another service fails, use the saved configuration and evidence to diagnose or roll back; do not keep making untracked edits.

What counts as a completed repair?

Record the original failure, changed dependency, DNS snapshot time and results for each affected service. A successful test from staff mail does not finish the review if the failing path was a billing system. Keep those paths separate in your evidence log.

An SPF pass resolves only that authentication question. If DMARC still fails, compare authenticated identities with the visible From domain using the linked guide. If the original result was a timeout, repeating a lookup-budget edit is unlikely to address the cause; return to the original diagnostic.

Source references

Worked examples are illustrative. Editorial procedures are suggested methods, not measured performance claims or promises of additional product features.

Related guides

Explore the Zintara workflow