Skip to content
email By Peter Mastras 7 May 2026 5 min read

The SPF 10-lookup limit: why it breaks email delivery

RFC 7208 caps SPF evaluation at 10 DNS lookups. Exceeding it invalidates your record and causes intermittent delivery failures. How to count lookups and fix it.

When you publish an SPF record, you list which mail servers can send email on behalf of your domain. Most of those listings come via include: statements referencing SPF records from cloud services — your CRM, support desk, transactional mail provider.

Each include: triggers a DNS lookup. RFC 7208 limits SPF evaluation to 10 DNS lookups total. Exceed that limit and the receiving server is allowed to treat your SPF as permanently erroring — returning permerror — which most providers treat the same as an SPF fail.

Why this accumulates

SPF records rarely start broken. They grow incrementally as services are added:

  • Exchange Online: include:spf.protection.outlook.com
  • Mailchimp: include:servers.mcsv.net
  • Salesforce: include:_spf.salesforce.com
  • Zendesk: include:mail.zendesk.com
  • Xero: include:_spf.xero.com

Each include: may contain nested include: statements, each costing another lookup. A record that looks like 5 includes can easily resolve to 12–15 actual lookups.

That pattern is exactly what we found at a Sydney professional services firm: seven cloud services added one at a time, resolving to 14 lookups, failing only at providers that enforce the limit strictly. We covered how we diagnosed and fixed it for that firm separately.

How to count your lookups

Trace the full include chain manually with dig:

dig TXT yourdomain.com

For each include: found, repeat for that domain. Count every include:, redirect=, a and mx mechanism — each is one lookup. ip4: and ip6: statements cost nothing.

Alternatively, use the Email Authentication Checker — it resolves your SPF record and reports the full include chain with a lookup count.

What counts as a lookup, and what doesn’t

This is where most manual counts go wrong. The limit is on DNS-querying mechanisms, not on the length of the record.

These cost one lookup each:

  • include: — and everything nested inside it
  • a and mx
  • ptr (deprecated, see below)
  • exists:
  • the redirect= modifier

These cost nothing:

  • ip4: and ip6: — the address is already in the record, so there is nothing to resolve
  • all
  • the exp= modifier, which is only evaluated when a message actually fails

So a record with twenty ip4: ranges and two include: statements is at two lookups, not twenty-two. A record with five include: statements and nothing else can be at fifteen. Length tells you nothing; structure is everything.

One extra trap: the mx mechanism resolves your MX records and then resolves each MX hostname. RFC 7208 caps that expansion at ten hosts, and exceeding it is its own permerror independent of the ten-lookup budget.

The void lookup limit nobody mentions

Separately from the ten-lookup budget, RFC 7208 limits void lookups — DNS queries that come back NXDOMAIN or with no relevant records — to two per SPF evaluation. Exceed that and you get permerror, even if your total lookup count is comfortably under ten.

This is the failure mode that catches records nobody has audited in years. A service is decommissioned, the provider eventually withdraws the SPF record the include: pointed at, and that include: becomes a void lookup. Three retired services in one record and SPF stops evaluating — with a lookup count that still looks fine on a naive count.

It is also why “the record has not changed, so it cannot be SPF” is bad reasoning. Your record does not have to change for it to start failing. Somebody else’s does.

permerror is not the same as fail

These are different results and the difference matters for diagnosis.

  • fail means SPF evaluated correctly and the sending IP is not authorised.
  • permerror means SPF could not be evaluated at all — a syntax error, too many lookups, or too many void lookups.

RFC 7208 leaves the handling of permerror up to the receiver, and that is precisely why an over-limit record produces symptoms that look random. Some providers treat it as a fail and reject. Some treat it as neutral and deliver. Some weight it as a spam signal without rejecting outright. Same message, same record, different outcome per recipient — which is exactly the pattern that sends people looking for a problem inside their own mail server.

For DMARC, however, there is no ambiguity: a permerror is not a pass, so it cannot contribute to DMARC alignment. A domain at p=reject with an over-limit SPF record is relying entirely on DKIM, whether it knows it or not.

Mechanisms to avoid entirely

ptr performs a reverse DNS lookup on the connecting IP and then forward- resolves the result. It is slow, it is unreliable, and RFC 7208 explicitly discourages publishing it. Some receivers skip it entirely. If you find ptr in a record, it is almost always a copy-paste inheritance from a decade-old template — remove it.

Be equally wary of +all, which authorises the entire internet to send as your domain. It appears more often than it should, usually as a misguided fix for delivery problems caused by something else.

How to fix it

Remove unused includes. Check each service listed — is it still actively sending as your domain? Many organisations keep includes for services retired years ago.

Flatten your SPF record. Instead of include:servers.mcsv.net, look up what IP ranges that resolves to and list them directly as ip4: statements. This eliminates the lookup cost for that service. The trade-off: if the provider changes their IP ranges you need to update your record.

Restructure nested includes. If multiple services include the same third-party SPF records, consolidate.

Use SPF macros. For high-volume senders with large IP ranges, macros allow per-message lookup evaluation without pre-publishing all IPs. This requires receiver support, which most providers have.

How to tell this is happening in production

You will not get a bounce that says “SPF permerror”. The signals are indirect:

  1. DMARC aggregate reports. If you have a rua= address, the reports carry the SPF result per source IP. A record over the limit shows up as SPF failing from sources that should obviously pass — your own mail platform included. This is the earliest reliable signal.
  2. Provider-specific failures. Delivery problems clustered at one or two recipient domains, while the rest of your mail flows normally, is the signature of a receiver-dependent permerror policy.
  3. A scheduled check. The lookup count is a number you can assert on. Any monitoring that resolves your SPF chain on a schedule and alerts above a threshold will catch a provider’s nested change before your recipients do.

That third one matters more than it looks, because this problem arrives without you doing anything. A provider adds one include: inside their own record and your count goes up overnight. Auditing SPF once at setup is not enough; it is a value that drifts on somebody else’s schedule.

The right target

Aim for 7 or fewer lookups. This leaves headroom for future services and handles providers that enforce stricter limits than the RFC requires.

After any SPF change, wait for DNS propagation (check your TTL) and re-verify with the Email Auth Checker.

Sources

Frequently asked questions

What is the SPF 10-lookup limit?
RFC 7208 caps SPF evaluation at 10 DNS lookups. Every include:, redirect=, a and mx mechanism costs one lookup; ip4: and ip6: statements cost nothing. Exceed 10 and the receiving server is allowed to treat your SPF as permerror, which most providers treat the same as an SPF fail.
How do I count the DNS lookups in my SPF record?
Run dig TXT yourdomain.com, then repeat the lookup for every include: you find, because includes commonly nest inside one another. A record with five visible includes can resolve to 12-15 actual lookups. The Edos Email Authentication Checker resolves the full include chain and reports the count for you.
How do I fix an SPF record that is over the limit?
Remove includes for services that no longer send as your domain, flatten a provider's include into explicit ip4: ranges, consolidate services that include the same third-party record, or use SPF macros for high-volume senders. Flattening trades lookups for maintenance: if the provider changes IP ranges, you must update the record.
What is a safe number of SPF lookups to aim for?
Aim for seven or fewer. That leaves headroom for services added later and covers providers that enforce stricter limits than the RFC requires. After any change, wait for DNS propagation based on your TTL and re-verify.

Need help with your email infrastructure?

Talk to an engineer