SPF permerror

SPF permerror and the Ten DNS Lookup Limit

Site owners
The short answer

SPF allows a maximum of ten DNS-querying mechanisms per check, and a record that exceeds it must return a permanent error called permerror. A permerror is not an SPF pass, so under DMARC the message fails authentication. You will not see an error that mentions SPF anywhere: what you actually receive is Gmail's 550 5.7.26 DMARC bounce, and the real cause only appears as spf=permerror in the message headers.

Seeing this on a site? Check it now.

Paste the address and we will tell you exactly which check is failing, and why. Free, and you do not have to open the site yourself.

If this is your site

Your SPF record has quietly stopped working. Not partially, not for some recipients. It is not being evaluated at all, and everything relying on it fails.

The reason this is so hard to diagnose is that the bounce never says SPF. It says DMARC. Look for spf=permerror in the Authentication-Results header of a test message, or in your DMARC aggregate reports, and you have your answer in one line.

Start here: there is no "SPF permerror" bounce

This is the single most confusing thing about the ten lookup limit, and it is why people spend days on it.

You will never receive a bounce message from Gmail that mentions SPF permerror, or too many DNS lookups, or the number ten. That message does not exist.

What happens instead is a chain. Your record blows the limit, so SPF evaluation returns permerror. A permerror is not a pass. DMARC only cares whether SPF passed and aligned, so it counts the permerror as a failure. If DKIM is not passing and aligning either, the message fails DMARC outright. And if your policy says reject, Gmail rejects it and sends you this:

550-5.7.26 Unauthenticated email from example.com is not accepted due to
550 5.7.26 domain's DMARC policy.

This is the bounce you actually get. It says DMARC, and there is nothing wrong with your DMARC record. The problem is two steps upstream in SPF. See our page on the 550 5.7.26 bounce for the other things that trigger it.

Where the truth is actually written down

Two places, both easy to check.

The first is the Authentication-Results header on any message you send to a Gmail address you control. Send yourself a test, view the original, and read the line.

Authentication-Results: mx.google.com;
       spf=permerror (google.com: too many DNS lookups) smtp.mailfrom=example.com;
       dkim=none;
       dmarc=fail (p=REJECT) header.from=example.com

There it is: spf=permerror. The second place is your DMARC aggregate reports, which show permerror across every source that relies on your SPF record. If you are not receiving those reports yet, our DMARC setup guide covers turning them on.

What the rule actually is

The limit comes from RFC 7208, the SPF specification. An SPF check may use at most ten mechanisms that require DNS queries. Exceed that and the implementation must return permerror. It is not a recommendation and receivers are not free to be generous about it.

The important detail is that the count is recursive. Every include: pulls in another record, and everything inside that record counts against your budget too. Three vendors with three lookups each are nine lookups, not three.

  • These count: include, a, mx, ptr, exists, redirect.
  • These do not count: all, ip4, ip6. IP addresses are literal values, so there is nothing to look up.
  • There is a separate limit too: at most two void lookups, meaning queries that return no answer. A vendor you removed whose domain no longer resolves can burn through that on its own.
  • Avoid ptr entirely. It is expensive, unreliable, and the specification discourages its use.

Why records drift over the limit

Nobody publishes a record with twelve lookups on day one. It creeps.

A record starts with the mail provider. Then marketing adds a newsletter tool. Then someone adds a helpdesk, an invoicing platform, a survey tool, a recruiting system. Each addition is one short include, each looks harmless, and each drags its own nested lookups in behind it.

The record works fine at nine lookups and breaks completely at eleven. There is no warning and no partial degradation. The mail was delivering yesterday and today it is bouncing, and the change that broke it was a single include added by someone who was not thinking about DNS budgets.

How to fix it

Work through these in order. The first two usually solve it on their own.

  1. 1.Count what you actually have. Expand every include recursively and add up the DNS-querying mechanisms. Any SPF checking tool will do this for you, and it takes a minute.
  2. 2.Remove vendors you no longer use. This is the highest-value step by a distance. Most over-limit records contain includes for at least one service the business stopped paying for years ago. Those are pure waste, and dead ones may be costing you void lookups too.
  3. 3.Replace includes with ip4 ranges where the vendor publishes stable ones. An ip4 mechanism costs nothing against the limit. Only do this where the vendor documents fixed ranges and commits to them, because if they change IPs without telling you, your mail stops.
  4. 4.Drop mechanisms you do not need. An mx mechanism is a lookup, and it only matters if your inbound mail servers also send outbound. Often they do not. Remove ptr if it is there at all.
  5. 5.Prefer CNAME-delegated sending domains. This is where the industry is heading, and it is the real long-term answer. Rather than an include in your SPF record, the vendor gives you CNAME records on a subdomain of yours and handles authentication under that subdomain. It never touches your ten lookup budget, no matter how many vendors you add.
  6. 6.Lean on DKIM. DMARC passes if either SPF or DKIM passes and aligns. Correct DKIM on every sender means an SPF problem stops being an outage. It is also the requirement for bulk senders anyway, as covered on the 550 5.7.30 page.

A note on delegated authentication

SendGrid is a good example of the CNAME approach in practice. Its Automated Security feature uses CNAME-based authentication, and it is on by default. With it enabled you point CNAME records at SendGrid from a subdomain of yours, and no include: is needed in your SPF record at all. That is one vendor removed from your lookup count without losing anything.

Check each of your own vendors for the equivalent. The language varies, and you will see it called domain authentication, sender authentication, branded sending or custom return path. If a vendor offers CNAME delegation, take it over an include.

One warning before you edit anything: publish exactly one SPF record per domain. Two TXT records both starting with v=spf1 is itself a permanent error, and it is a mistake people make while trying to fix the lookup limit. Our SPF setup guide covers the record structure, and the fix library has the rest.

Frequently asked questions

Does the limit count the includes I wrote, or all of them?

All of them. The count is recursive, so every record pulled in by an include contributes its own DNS-querying mechanisms to your total. A record with four includes can easily be using twelve lookups. This is why counting by eye almost always underestimates.

Do ip4 and ip6 entries count?

No. Neither do all. Those are literal values that require no DNS query, so you can list as many IP ranges as you like without touching the limit. The mechanisms that count are include, a, mx, ptr, exists and redirect.

Why did my mail work yesterday and bounce today?

Almost certainly because someone added an include, or because a vendor changed their own record and it now expands to more lookups than it used to. You do not control what is inside a vendor include. Their change can push your record over the limit without anyone at your company touching anything.

Is permerror the same as fail?

No, but the practical outcome under DMARC is the same. A fail means the sending server is definitely not authorised. A permerror means the record could not be evaluated at all. Either way it is not a pass, so DMARC treats it as a failure and your policy is applied.

What is a void lookup?

A DNS query that comes back with no answer, either an empty result or a name that does not exist. SPF allows at most two of them, separately from the ten lookup limit. They usually come from includes pointing at domains that have been decommissioned, which is another reason to remove vendors you no longer use.

Related errors

See all errors explained →

Stop guessing what is wrong.

Run a free check on any site and see every trust and security signal at once, in plain English.

Run a free check Browse the fixes