Developer documentation

SPF too many DNS lookups

What the SPF 10-lookup limit counts, why a record returns permerror, and how to use the SPF checker without treating its inventory as a pass or fail.

Receivers that evaluate SPF stop after 10 DNS lookups on the path they actually walk. Past that, the result is a permanent error. Logs often say permerror, or "too many DNS lookups". That is not a missing record, and it is not the soft fail you get from ~all.

What counts toward the 10

RFC 7208 counts DNS-querying mechanisms on the evaluated path: include, a, mx, ptr, exists, and redirect. An include also counts the lookups inside the included record, along the branch the receiver follows. ip4 and ip6 do not need a lookup. all does not either.

One message uses one path. A record that includes three providers does not make the receiver look up all three if the first one already matches the sending IP. The limit is about that walk, not about the total size of the tree on paper.

What the SPF checker is counting

The SPF checker has no sender IP, so it explores the include and redirect branches it can see and totals the lookup-triggering terms. That inventory can be higher than the lookups for any single message. It does not fully evaluate a, mx, ptr, exists or macros. Use it to find unused includes and duplicate records. Do not treat the number as a pass or fail of the 10-lookup rule.

How a record gets here

The usual cause is a stack of include mechanisms: one for the app, one for a newsletter tool, one for support software, one for an old provider that is still in the TXT record. Each of those providers has their own includes. Ten is easy to cross once the old names are still published.

A second v=spf1 TXT record on the same name is a different failure. SPF requires a single record. Combine the senders you still use into one, instead of adding another.

What to change

  1. List the services that still send as your domain. Remove include mechanisms for the ones that do not.
  2. Keep one SPF record on the name. If your DNS host split one record into quoted strings, that is still one record. Two separate TXT records that both start with v=spf1 are not.
  3. Recheck after you edit. An included provider can add lookups on their side later, which changes your total without a change in your own TXT record.

Flattening a record into a long list of IP addresses avoids lookups until those addresses change. If you do that, you have to refresh it when the provider changes their servers. Removing unused includes is the change that stays readable.

For the SendPanda return path, copy the SPF name and value from the domain screen. Do not replace your root-domain policy with a provider example if other services still send as that domain. The domain setup guide covers that name, and SPF, DKIM and DMARC covers how SPF fits next to the other two records. The mechanism limit is in RFC 7208 section 4.6.4.

Next steps