Guides

SPF's 10-lookup limit and how to get under it

Last updated 2026-08-28

RFC 7208 caps SPF evaluation at ten DNS-querying mechanisms. It is not a guideline and receivers do not round up. The eleventh lookup turns a correct-looking record into one that authorises nobody.

Why does a limit exist at all? Because SPF evaluation happens during an SMTP transaction, and an unbounded record is a denial-of-service amplifier: publish a record with a thousand nested includes and every receiver checking it does a thousand lookups on your behalf. Ten is the number the spec landed on.

What each mechanism costs

Mechanism Lookups Notes
ip4: ip6: 0 Free, always. The cheapest way to authorise a server you control.
all 0 Free.
include: 1 Plus everything the target record spends.
a 1 Resolves the domain's A and AAAA records.
mx 1 One term against this limit. The address queries behind it sit under RFC 7208's own separate cap.
exists: 1 Uncommon outside macro-based setups.
ptr 1 Deprecated. Delete it.
redirect= 1 Plus the target record's own spend.

There is a second, smaller budget: at most two void lookups, meaning queries that come back empty. An include pointing at a service you cancelled burns one of those every time anyone checks your record.

A worked example

Here is a record I have seen versions of at half a dozen companies. The counts are what the checker reported on the day, since providers change what is inside their own includes without telling anyone.

v=spf1 mx a include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net include:servers.mcsv.net include:mail.zendesk.com -all
Term Cost Why it is there
mx 1 One term; MX address resolution has a separate limit
a 1 The web server, which does not send mail
_spf.google.com 1 Flat when checked on 2026-08-20
spf.protection.outlook.com 1 Left over from a migration two years ago
sendgrid.net 2 Transactional mail, plus one nested include
servers.mcsv.net 1 Marketing
mail.zendesk.com 1 Helpdesk
Total 8 Working, with 2 lookups left.

Six of those eight lookups come from stacked includes, leaving room for only 2 more. Three of the 8 are doing no work at all. The a mechanism authorises a web server that has never sent an email. The mx mechanism authorises your inbound servers to send outbound, which they do not. The Microsoft include is a fossil from a migration. Deleting all three costs nothing and puts the record at 5.

v=spf1 include:_spf.google.com include:sendgrid.net include:servers.mcsv.net include:mail.zendesk.com -all

The four moves, in the order I use them

1. Delete what you do not use

Free, and it fixes more records than any other move on this list. It holds until someone adds the next include, which is why the inventory is worth keeping. Every over-limit record I have looked at contained an include for a product that had been cancelled, a migration that finished, or a trial nobody converted. Check each include against something that bills you. The sending routes check reads which includes still carried mail in your own reports over the last 90 days and gives each one a keep, review or remove verdict, on a paid plan.

2. Use ip4 literals for your own servers

If you control the address and it does not change, a literal costs nothing and cannot break. This applies to your own relay, your office NAT and a VPS you send from. It does not apply to a provider, whose addresses change on their schedule.

v=spf1 ip4:203.0.113.24 ip4:198.51.100.0/28 include:_spf.google.com -all

3. Split by subdomain

The structural fix, and the one worth doing before you are in trouble. Give each heavy platform its own sending subdomain, each with its own SPF record and its own fresh budget of ten.

example.com TXT "v=spf1 include:_spf.google.com -all" news.example.com TXT "v=spf1 include:servers.mcsv.net -all" mail.example.com TXT "v=spf1 include:sendgrid.net -all"

The From address moves to the subdomain too. Relaxed DMARC alignment, which is the default, treats news.example.com as aligned with a policy on example.com, so nothing about DMARC breaks. As a bonus, a marketing platform's reputation problem stops being your invoicing platform's problem.

If you have set aspf=s for strict alignment, subdomains stop aligning and this move breaks everything. Check which mode you are in first.

4. Flatten, last and reluctantly

Flattening means resolving an include yourself and pasting the resulting IP ranges in as literals. It works. It also means your record is a frozen snapshot of somebody else's infrastructure, and when they renumber, your mail fails and nothing in your DNS looks wrong.

If you flatten, flatten only providers whose ranges are stable, keep the original include in a comment somewhere a human will find it, and check the result on a schedule you will keep. Automated flattening services solve the staleness by rewriting your record for you, which means handing a third party write access to the DNS record that controls who can send as your domain. I would not.

Measuring it

You cannot count this by hand reliably, because the includes have includes and they change. Our SPF checker resolves the full chain, prints the tree, and gives you the total against the limit. Run it after every change, and run it occasionally when nothing has changed, because the number moves when your providers edit their own records.

To see one chain by hand:

dig +short TXT example.com dig +short TXT sendgrid.net dig +short TXT ab.sendgrid.net

The second line answered with include:ab.sendgrid.net inside it when I ran this on 2026-08-20, and the third line is that nested include resolved by hand. A chain one level deep is a short one; some providers nest further.

The part people get backwards

An SPF record in permerror is a serious problem and it is not usually the most urgent one. DKIM has no lookup budget, survives forwarding, and is enough on its own for DMARC to pass. A domain with correct DKIM everywhere keeps working through an SPF outage; a domain leaning entirely on SPF does not survive a single recipient setting up a forwarding rule.

So fix the record, and while you are in there, check that every one of those platforms is also signing with your domain. The provider pages list what each one needs, and the permerror page is the short triage version of this guide for when something is already bouncing.

Point your rua= tag at a mailbox someone reads. We parse that XML and mail you the senders that used your domain and whether each one passed. Paid plans add an alert the day a report first names a new sender failing. One free domain, no card.

Run the ramp on real reports

Every step in this guide depends on a few weeks of aggregate reports. We parse them and mail you a weekly summary: the senders that used your domain, what failed, and when tightening the policy is safe. Paid plans email you the day a new source first fails. Your first domain is free.

Get the weekly digest

No card · 12+ months of history · The free plan does not expire

Questions

What happens at the eleventh lookup?

Evaluation stops and SPF returns permerror. Not a softfail, not a partial result. The record authorises nothing, including the servers listed before the limit was reached.

Does the limit apply per include or across the whole record?

Across the whole evaluation, including everything nested inside every include. That is why one provider whose include contains four more can put you over on its own.

Is there a limit on the size of an SPF record?

A single TXT string is capped at 255 characters, and longer records are split into several strings that resolvers concatenate. That works, but a record long enough to need it is usually a record that needs restructuring.

DomainCanary is a DMARC monitoring service that turns your domain's aggregate reports into one weekly email.