Skip to main content

The SPF 10-DNS-Lookup Limit: Why Your Email Authentication Silently Fails

The SPF 10-DNS-lookup limit silently breaks email authentication with permerror. How includes stack up, how to count lookups, and the fixes that work.

The CompleteStatus Team 6 min read

The SPF 10-DNS-Lookup Limit: Why Your Email Authentication Silently Fails

Want this checked continuously?

CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.

Monitor your site free

SPF has a hard ceiling almost nobody remembers until it bites: evaluating a record may trigger at most 10 DNS lookups. Cross that limit and receivers return permerror, a permanent evaluation error that means your SPF effectively doesn't exist. No bounce lands in your inbox and no dashboard turns red; your mail just quietly loses one of its two authentication legs. And because every SaaS tool you onboard says "just add our include: to your SPF record," most growing companies drift over the limit without changing anything on purpose.

This post covers why the limit exists, what counts toward it, how to audit your own record, and the fixes that hold up.

Why the limit exists

SPF records are evaluated by the receiving server, live, on every inbound message. Each include: is a DNS query that server must make, and includes can nest, so a single record could fan out into dozens of queries. RFC 7208 caps the fan-out at 10 lookups so attackers can't use the world's mail servers to amplify DNS denial-of-service traffic. The cap is not advisory: the RFC says exceeding it must produce permerror.

What counts toward the 10 (and what doesn't)

Mechanisms that count, each time they appear, including inside nested includes:

  • include:: one lookup per include, plus whatever the included record spends
  • a and mx: one each
  • ptr: one (and it's deprecated; remove it on sight)
  • exists:: one
  • redirect=: one

Mechanisms that are free: ip4:, ip6:, and all. They're literal data, so no DNS is required. Most of the fixes below exploit that asymmetry.

There's a second, lesser-known tripwire: RFC 7208 also recommends allowing at most 2 void lookups (queries that return no answer or NXDOMAIN) before returning permerror, and many receivers enforce it. A couple of stale includes pointing at dead hostnames can kill an otherwise-legal record.

How real records blow the budget

Here's an ordinary record for a company using Google Workspace, Microsoft 365 for one team, and two sending services:

v=spf1 include:_spf.google.com include:spf.protection.outlook.com
       include:sendgrid.net include:mailgun.org a mx ~all

Looks like four includes plus two cheap mechanisms. Now expand it. As of writing, _spf.google.com contains three nested include: mechanisms of its own (_netblocks, _netblocks2, _netblocks3), so Google alone costs 4 lookups. Add roughly 1–2 for Microsoft, 1 each for SendGrid and Mailgun, plus your a and mx:

Google        4
Microsoft     1–2
SendGrid      1
Mailgun       1
a             1
mx            1
              ─────
              9–10

You're at the edge with an entirely ordinary setup. The next "just add our include" email from a marketing tool pushes you over, and nothing announces it. (Third-party records change over time, so treat these counts as a snapshot and recount after any provider migration.)

Why the failure is silent

Two reasons permerror hides so well. First, receivers don't notify senders; the error happens on their side, per message, and simply feeds into filtering. Second, DKIM usually masks it: if your mail also carries an aligned DKIM signature, DMARC still passes on the DKIM leg and delivery mostly continues. You're now standing on one leg. The day DKIM breaks (a key rotation goes wrong, a provider config lapses) you have zero passing authentication, and if you've moved your DMARC policy to quarantine or reject, your own mail starts getting junked or refused.

permerror is also worse than a plain fail under DMARC: it can't be salvaged, and some receivers treat a domain with a permanently broken SPF record with extra suspicion.

How to count your lookups

Do it by hand once; it's instructive. Pull your record:

dig +short TXT yourdomain.com | grep spf1

Then recursively dig every include: and redirect= you find, tallying as you go with the rules above. You can run the same queries in the browser with the free DNS lookup tool: query TXT for your domain, then for each included hostname, and keep a running count. Remember: a, mx, ptr and exists in any level of the tree count too, not just includes.

Fixes that actually work

In order of preference:

  1. Delete what's dead. Old includes for tools you cancelled two years ago are the most common finding. Removing them wins lookups back and removes void-lookup risk.
  2. Drop a and mx if redundant. If the hosts they resolve to are static, replace them with explicit ip4: mechanisms, which cost nothing.
  3. Question whether each service needs to be in SPF at all. DMARC checks SPF against the envelope (Return-Path) domain. Many sending services use their own bounce domain, so their SPF pass can never align with your From domain anyway. For those, aligned DKIM is what earns the DMARC pass, and their include: in your record is dead weight. Check the provider's docs before cutting, but this one move often reclaims several lookups.
  4. Split senders across subdomains. Send marketing from mail.yourdomain.com with its own SPF record and its own 10-lookup budget. This also isolates reputations, which is worth doing anyway.
  5. Flatten, as a last resort. See below.

Flattening: pros and cons

Flattening replaces include: mechanisms with the literal ip4:/ip6: blocks they currently resolve to. The pro is real: lookups drop to near zero. The cons are why it's last on the list:

  • Providers change their IP ranges without telling you. The moment they do, your flattened record authorises the wrong servers, and legitimate mail starts failing SPF. Flattening is only safe when something re-resolves and republishes the record automatically, which turns a one-time fix into a piece of infrastructure you must run forever.
  • The record gets huge. Long records need splitting across multiple TXT strings, and are painful to review by eye.
  • You lose auditability. include:_spf.google.com documents intent; forty raw CIDR blocks don't.

If you can get under 10 with steps 1–4, do that instead.

Catch the drift before permerror does

SPF records usually break through accumulation rather than one mistake: every new tool adds an include, and the record that passed last quarter fails this one. CompleteStatus monitors your SPF, DKIM and DMARC records and alerts you if SPF or DMARC disappears, and flags weak policies such as +all or p=none. Add a DNS monitor on your domain's TXT records and any edit to the SPF record is flagged too, so you can recount before receivers do it for you. All of it sits alongside uptime, SSL and security-header monitoring in one dashboard.

Check your domain's email authentication now with the free DMARC / SPF / DKIM checker, then start monitoring free so the next silent change isn't silent. The free tier allows commercial use.

Written with AI assistance and reviewed by the CompleteStatus team.