LearnEmail authentication

SPF: too many DNS lookups

SPF permits a maximum of 10 DNS lookups while evaluating a record, counting every include, a, mx, exists and redirect, including nested ones. Cross the limit and evaluation stops with a permanent error, which receivers treat as having no SPF record at all — not as a partial pass.

Written by the SieveGuard team from the checks our own free tools run. Last reviewed .

Why this breaks setups that nobody touched

The count is not of the mechanisms in your record. It is of every lookup performed while resolving it, including the ones inside your providers’ records. Your record can be unchanged for two years and still cross the line the day a provider adds an include: to theirs.

When it happens the result is total, not partial: evaluation halts at the eleventh lookup and returns permerror. Under DMARC a permerror is not a pass, so a domain relying on SPF for alignment loses it, everywhere, at once. That is the signature of this failure — mail that was fine yesterday failing from every sender simultaneously with no change on your side.

What counts and what does not

MechanismCosts a lookup?Note
include:Yes — 1, plus everything inside itThe compounding one
aYes — 1Plus one more per additional name
mxYes — 1, plus one per MX host returnedA 5-host MX costs 6, not 1
exists:Yes — 1Rare in hand-written records
redirect=Yes — 1, plus the target’s own lookupsCounts even though it is a modifier
ip4: / ip6:No — freeThe basis of every fix below
allNoTerminates evaluation

The mx row is the one that catches people. It is a single token in your record and it can cost six lookups on a domain with five mail exchangers. There is a separate, less-known cap of 10 on ptr/mx host expansions inside a single mechanism, but you will hit the main limit first.

What each provider costs you

Counts at the time of writing, resolved from each provider’s published record. Treat them as indicative rather than fixed — the number changing under you is the entire subject of this page. Re-count yours with the command below rather than trusting any table, including this one.

ProviderIncludeApprox. lookups
Google Workspace_spf.google.com4
Microsoft 365spf.protection.outlook.com3
SendGridsendgrid.net3
Mailchimpservers.mcsv.net2
Amazon SES (regional)amazonses.com2
Zoho Mailzoho.com3
Brevospf.brevo.com2
Salesforce_spf.salesforce.com4
HubSpot_spf.hubspot.com2
Zendeskmail.zendesk.com2

Add them up and the arithmetic is unforgiving. Google plus Salesforce plus SendGrid is already eleven before you have listed a single server of your own — and each include: token costs one on top of what it resolves to.

Counting yours

The recursive count is what matters, so expanding one level by hand is not enough. Walk the tree:

dig +short TXT yourdomain.com | grep spf1
# then, for every include: you find, repeat on that name
dig +short TXT _spf.google.com
dig +short TXT sendgrid.net

Keep going until nothing new appears, counting one for every include, a, mx, exists and redirect encountered anywhere in the tree. Or skip the arithmetic — our SPF checker resolves the chain and reports the count.

Getting back under the limit

Remove senders you stopped using

Always first, always the biggest win, and almost always available. Records accumulate providers the way a codebase accumulates dependencies — the trial ESP from three years ago is still in there costing three lookups. Nothing else on this list is free; this one is.

Replace an include with the IPs behind it

ip4: costs nothing. If a provider publishes a stable, small range, inlining it converts several lookups into zero:

before:  include:mail.example-esp.net        → 2 lookups
after:   ip4:198.51.100.0/24 ip4:203.0.113.9  → 0 lookups

The trade is real and worth stating plainly: you have taken on the job of noticing when that provider changes their IPs, and they will not tell you. Only do this for providers who publish a stable range and document it, and put a calendar reminder against it.

Move bulk sending to a subdomain

The cleanest structural fix. Each domain gets its own budget of ten, so splitting senders across names multiplies the budget instead of rationing it:

yourdomain.com        v=spf1 include:_spf.google.com ~all          → 4 of 10
mail.yourdomain.com   v=spf1 include:sendgrid.net ~all            → 3 of 10
news.yourdomain.com   v=spf1 include:servers.mcsv.net ~all        → 2 of 10

It also separates reputation: a marketing campaign that generates complaints damages news.yourdomain.com and leaves your corporate mail alone. That benefit usually outlives the lookup problem that prompted the change.

SPF flattening — understand the trade first

Flattening resolves every include to literal IPs and publishes the result. It always works and it is the option most likely to hurt you later:

  • The record goes stale silently. When Google rotates a range, your flattened copy still lists the old one. Mail from the new servers fails SPF and nothing announces it.
  • It gets long. Flattening Google alone runs to several hundred bytes, which drags in the 255-byte string-splitting rules.
  • Automated flatteners add a dependency. A third party now controls a DNS record that gates your mail, and their outage is your outage.

Reach for it when subdomain separation is genuinely not available, not as the first answer.

Sources

FAQ

What is the exact SPF lookup limit?+

Ten DNS-querying mechanisms per evaluation, defined in RFC 7208 section 4.6.4. It counts include, a, mx, exists and redirect, including every one encountered inside nested records. Exceeding it must return permerror.

What happens when I exceed it?+

Evaluation stops and returns a permanent error. Receivers treat permerror as no SPF result at all, so under DMARC you lose SPF alignment completely. It is not a partial pass and it is not a warning.

Do ip4 and ip6 mechanisms count?+

No. They resolve nothing, so they are free. That is why every fix for this problem eventually involves converting lookups into literal addresses, and why a record full of ip4 entries can be long without being at risk.

Why did my SPF suddenly break when I changed nothing?+

Because the count includes your providers’ records, not just yours. When a provider adds an include to their own record, every domain that includes them gains that lookup. Domains sitting at nine or ten cross the line the same day, without any change on their side.

Is SPF flattening safe?+

It works, but it moves a maintenance burden onto you. Flattened records go stale silently when a provider rotates IP ranges, and mail from the new servers then fails SPF with nothing to announce it. Prefer removing unused senders or splitting across subdomains first.

Does the limit apply per domain or per message?+

Per evaluation, which in practice means per domain being checked. Each domain and subdomain gets its own budget of ten — which is exactly why moving bulk senders onto a subdomain is the most durable fix available.

Check it on a real domain

Free, no signup, DNS-only. Nothing you type leaves the lookup.

Keep reading