SPF include: Over 10 Lookups Does Not Fail Every Message

An SPF record that needs more than ten DNS lookups is broken, but not in the way most guides describe it. Evaluation stops at the first mechanism that matches the connecting server, so a sender matched by the second term never reaches the twelfth. Going over the limit means the record can return a permanent error, and does for every sender not matched earlier in the record. Order decides who is affected.

That distinction matters because it changes the fix. If the limit broke every message you would notice immediately. Instead it breaks the senders sitting at the end of your record, which is usually the platform you added most recently and check least often.

include tells the receiver to go and check another record

The include mechanism does not copy another domain's record into yours. It tells the receiving server to evaluate that other domain's SPF record as a separate check and use the result: if the connecting IP passes there, the include matches and evaluation stops.

v=spf1 include:_spf.google.com include:sendgrid.net ~all

That record says: check Google's list, then check SendGrid's list, then apply ~all to anything that matched neither. Each include hands the receiver a fresh record to parse, which may itself contain more include terms, which is where the budget goes.

The word is misleading in one specific way. include returns only a pass or a no-match. A -all inside an included record does not reject your mail; it simply means that record did not match, and evaluation continues with your next term. Only the all in your own record decides the outcome.

Five mechanisms spend the budget, and three are free

RFC 7208 section 4.6.4 caps a single SPF evaluation at ten DNS-querying terms. Exceeding it is a MUST-level permanent error, not a soft warning.

TermCosts a lookup
includeYes, plus everything inside it
aYes
mxYes
ptrYes, and it is deprecated
existsYes
ip4No
ip6No
allNo
expNo

Two details in that table are commonly got wrong. An mx term costs one lookup for the term, not one per MX record returned, and a record listing a hundred IP addresses with ip4 spends nothing at all. That second point is the whole basis of SPF flattening.

The %{p} macro is also charged to the same budget of ten, because expanding it requires a reverse lookup.

The count is of terms evaluated, not of domains named

This is the rule that makes a record cost more than it looks like it costs. The limit counts every DNS-querying term a receiver evaluates during one check, and a domain reached down two different branches is evaluated twice.

If your record includes two vendors and both of them include the same shared infrastructure domain, that shared domain's entire subtree is paid for twice. Counting distinct domain names gives you a number lower than the one a receiver will reach, which is why a record that looks like six lookups on paper can permerror in practice.

Two related cases have the same flavor:

  • A loop is a permanent error, not a branch to skip. If A includes B and B includes A, a receiver does not quietly stop; it fails the record.
  • Terms after all are never evaluated. all always matches, so anything following it is dead code and costs nothing. A redirect sitting beside an all is inert for the same reason.

Over the limit fails the senders at the end of your record

A receiver evaluates your terms in order and stops at the first match. That produces three different outcomes from one broken record, depending on who is sending.

  • A sender matched before the budget runs out passes normally. Nothing is wrong for them, and nothing appears in your logs.
  • A sender matched after the tenth lookup gets a permanent error. Most receivers treat a permerror as a failure rather than as a missing record, so DMARC sees no SPF pass.
  • A sender not in your record at all hits your all term, exactly as designed, if evaluation survives that far.

So the practical symptom is one platform's mail suddenly failing authentication while everything else looks fine. If that platform was added to the end of the record, it is the first to fall off the edge.

This also means a fix can be free. Moving your highest-volume sender to the front of the record does not reduce the total, but it does mean that sender is matched before the budget is spent. It buys time rather than solving the problem.

How to find the real number

Counting by hand is unreliable because you cannot see inside a vendor's record without resolving it, and vendors change theirs without telling you. Run the domain through a free SPF checker, which walks the whole tree, resolves each include recursively and reports the total a receiver would actually reach rather than the number of terms you typed.

What to look for in the result:

  1. The total against the limit of ten. Anything over means the record can permerror.
  2. Which branch is expensive. One vendor is usually responsible for most of the cost, and vendors differ enormously.
  3. Duplicated subtrees. Shared infrastructure reached twice is the commonest hidden overrun.
  4. Void lookups. A term resolving to nothing has its own separate budget, and an include pointing at a domain with no SPF record is a permanent error on the first occurrence.
  5. Anything after all. Dead terms are harmless but they are usually a sign the record has been edited by several people who did not read it.

Across the domains we test for the Unspam 2026 Email Deliverability Benchmark, 93% publish a valid SPF record, so the common failure in this area is not an absent record but a record that has quietly outgrown its budget.

Four ways to get back under ten

In rough order of how much you should prefer them.

Remove what you no longer use. Most overrun records carry a vendor nobody has sent through in two years. This is free, it is permanent, and it is almost always available.

Replace an include with ip4 ranges where the vendor publishes stable ones. An ip4 term costs nothing. The catch is that you now own the maintenance: when the vendor changes IPs, your mail fails and nobody tells you. Only do this where the vendor documents a stable range and commits to notifying changes.

Move sending to a subdomain. Your marketing platform can send from mail.example.com with its own SPF record and its own budget of ten. This is the structural fix, it scales, and it has the side benefit of separating reputations.

Flatten the record with a service. SPF flattening resolves every include and publishes the resulting IP list for you, refreshing it automatically. It works, and it makes a third party's uptime a dependency of your mail authentication. Treat it as the last option rather than the first.

If you are building a record rather than repairing one, an SPF record generator produces a correct starting record, and our guide to SPF records covers the syntax in full.

What to check once the record is under the limit

SPF passing is necessary but it is not enough on its own, because DMARC needs the SPF domain to align with the address in your From header, and SPF breaks on forwarding no matter how tidy the record is. Our guide to email authentication covers how the three records depend on each other and why DKIM, not SPF, is the one that survives a mailing list.

Re-check the total whenever you add a sending platform, and again a few months later even if you changed nothing, because the count includes vendors' records and those move under you. To see what a real message looks like at a receiver, including the SPF result next to everything else that decides placement, run a free spam test.

Frequently asked questions

What does include do in an SPF record?

The include mechanism tells the receiving server to evaluate another domain's SPF record as a separate check and use the result. It does not copy that record into yours. If the connecting IP passes at the included domain, the include matches and evaluation stops there. A -all inside an included record does not reject your mail either; it only means that record did not match, and evaluation continues with your next term. Only the all in your own record decides the outcome.

How many DNS lookups is an SPF record allowed?

Ten, under RFC 7208 section 4.6.4, and exceeding it is a MUST-level permanent error rather than a warning. Five mechanisms spend that budget: include, a, mx, ptr and exists. Three do not: ip4, ip6 and all, and the exp modifier is free as well. The %{p} macro is charged to the same limit because expanding it requires a reverse lookup. An mx term costs one lookup for the term, not one per MX record returned.

Does going over ten lookups break every message?

No, and this is the detail most guides get wrong. A receiver evaluates your terms in order and stops at the first one that matches the connecting server, so a sender matched by the second term never reaches the twelfth. Going over the limit means the record can permerror, and does for every sender not matched earlier in the record. The usual symptom is one platform's mail failing authentication while everything else looks fine, and that platform is normally the one added most recently, at the end of the record.

Why does my SPF record use more lookups than terms I wrote?

Because the limit counts every DNS-querying term a receiver evaluates, not the number of domains you named. Each include hands the receiver a fresh record which may contain more include terms, and a domain reached down two different branches is evaluated twice, so its whole subtree is paid for twice. Two vendors that both include the same shared infrastructure is the commonest hidden overrun, and counting distinct names gives a number lower than the one a receiver reaches.

Is SPF flattening a good idea?

It is the last option rather than the first. Flattening resolves every include and publishes the resulting IP list, refreshing it automatically, which does solve the lookup count. It also makes a third party's uptime a dependency of your mail authentication. Prefer removing vendors you no longer use, which is free and permanent, then replacing an include with ip4 ranges where the vendor publishes stable ones, then moving a platform to a subdomain with its own record and its own budget of ten.

Can I have two SPF records on one domain?

No. Publishing a second TXT record rather than editing the first does not merge them, and the result is a permanent error. Most receivers treat a permanent error as a failure rather than as a missing record, so DMARC sees no SPF pass. One domain gets one SPF record, and everything you authorize goes inside it.

See where your campaign actually lands.

Start a free spam test Inbox placement test