July 6, 2026

The SPF ten-lookup limit, and why your record fails silently


Most SPF problems are invisible. The record is published, it parses, your DNS panel shows a green check, and mail still lands in spam. The record looks right and does nothing. There is usually one reason, and it is a number.

The limit

SPF is defined by RFC 7208. When a receiving server evaluates your record, every mechanism that requires a DNS query counts against a budget: include, a, mx, ptr, exists, and redirect. The budget is ten. Not ten include statements — ten lookups, counted recursively.

That recursion is where it goes wrong. Each include pulls in another domain's SPF record, and that record has its own include statements, which pull in more. A single line in your record can cost you five lookups you never see.

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

Four include statements. But _spf.google.com alone expands to three lookups. Add the others and you are already past ten before your own domain is counted.

What happens at eleven

When evaluation exceeds ten lookups, the receiving server does not ignore the extra mechanisms and carry on. It returns a permerror — a permanent error — and treats the entire SPF result as unusable. Not "fail." Not "the last few senders aren't authorized." The whole record is discarded.

So a domain with a carefully maintained SPF record, listing every legitimate sender, can authenticate none of them. The record is syntactically perfect. It has simply been switched off by a counter.

Why your DNS panel doesn't warn you

Your DNS host validates syntax. It checks that v=spf1 is present, that the mechanisms are well-formed, that there is a terminating all. It does not resolve the include chain and count the lookups, because that requires making the same recursive queries a receiving server makes — something a record editor is not built to do.

This is why "the record is fine, I checked it" and "mail is failing" coexist so often. Both statements are true. The record is fine as text. It fails as a lookup.

How it gets fixed

You cannot raise the limit; it is fixed by the specification. You reduce the lookups. The usual moves:

The goal is a single record, under ten lookups, that still authorizes every system genuinely sending as you. Getting there means first knowing which systems those are — which is a different problem, and usually the harder one.

You can see your own count in four seconds: check your domain. If it reports more than ten, the record is published and doing nothing, and no amount of editing the content will fix a problem that is about the count.