SPF PermError: what it means and how to fix it
By Thomas · virtual CISO · 2026-07-07
Of all the results an SPF evaluation can return, the PermError is the most treacherous. It's neither a pass nor a fail: it's a permanent error meaning your record is impossible to evaluate correctly. To the receiving server, it's almost as if your SPF didn't exist — with, on top of that, a negative signal for DMARC. The trap is that your mail is perfectly legitimate; only your record is broken. This guide explains what a PermError really is, its main causes, and how to diagnose then fix each one.
The possible results of an SPF evaluation
To place the PermError, you need to know the seven results SPF can produce:
pass— the IP is authorized.fail(hardfail) — the IP isn't authorized, clear signal (-all).softfail— probably not authorized, soft signal (~all).neutral— no position (?all).none— no SPF record at all.temperror— a temporary error (often a passing DNS glitch); to retry.permerror— a permanent error: the record is invalid or unevaluable.
PermError and TempError are often confused. The distinction is crucial: a TempError usually resolves on its own (network, momentary DNS), whereas a PermError will never go away until you fix your record.
Why a PermError is dangerous
A PermError doesn't "block" your mail directly, but it strips your domain of all SPF protection and, above all, weighs on DMARC. For DMARC, an SPF in PermError neither aligns nor passes. If DKIM doesn't save the message, it fails DMARC — and depending on your policy (quarantine, reject), it goes to spam or gets refused. In other words: a broken record can send your own legitimate mail into the wall. That's why a PermError gets fixed fast.
Cause #1: too many DNS lookups
By far the most common cause. RFC 7208 limits evaluation to ten DNS resolutions. Each include, a, mx, ptr, exists and redirect consumes one, and provider includes unfold in cascade. Exceed ten, and it's PermError. It's so common we devote a whole guide to it: the 10-lookup limit. The fix goes through cleaning out unnecessary includes, splitting by subdomain, or a controlled flattening.
Cause #2: too many "void lookups"
More discreet, but very real. A void lookup is a DNS resolution that returns nothing (non-existent domain or empty record). The RFC limits the number of these empty resolutions to two. Past that, it's also a PermError. The typical cause: an include pointing to a deleted provider domain, or a typo in a domain name. The symptom is sneaky because the record "looks" correct — you have to unfold each mechanism to spot the ones that resolve to nothing.
Cause #3: invalid syntax
A simple typo can break the whole record: a malformed ip4:, an include without a colon, a stray character, two mechanisms stuck together without a space. SPF is strict: if the receiver's parser can't interpret a mechanism, it returns PermError rather than guessing. Re-read carefully, or — safer — have the syntax validated by a tool.
Cause #4: a duplicate SPF record
A domain must have only one v=spf1 record. If two exist (one set by IT, another by marketing, say), the situation is ambiguous and many receivers return PermError — or ignore both. The fix: merge the two into a single record, combining their mechanisms and checking you don't exceed ten resolutions along the way.
Cause #5: obsolete or forbidden mechanisms
Some mechanisms cause trouble. The ptr, for example, is discouraged by the RFC: slow, unreliable, it can contribute to a PermError and should be removed. Likewise, exotic SPF macros or misplaced modifiers can make the record unevaluable. As a rule, a healthy SPF sticks to include, ip4, ip6, a, mx (sparingly) and the terminal qualifier.
A PermError dissected: a real case
Take a domain that just tipped into PermError without warning. The team swears it "changed nothing." Let's unfold it. The record:
v=spf1 include:_spf.google.com include:_spf.old-router.com
include:mail.partner.com include:_spf.salesforce.com include:servers.mcsv.net -all
First pass in the analyzer: two problems coexist. First, include:_spf.old-router.com resolves to nothing — the provider shut its service six months ago. That's a void lookup, and there's a second one, further along, on a dead subdomain. Two void lookups is the limit; one more tips it over. Then, unfolding the remaining includes, you count eleven resolutions: the ten-lookup limit is also exceeded. Two stacked PermError causes, which explains why an "eyeball" diagnosis had failed.
The fix is in two steps. First, remove the two dead includes (old-router and the defunct subdomain): no mail goes out from those sources anyway. That simple cleanup removes the void lookups and drops the count to eight or nine resolutions. Then, since the margin stays thin, move Mailchimp (servers.mcsv.net) to a news. subdomain with its own SPF. The root domain falls comfortably under the bar, with no void lookup. PermError resolved — and the real lesson is that "we changed nothing" is almost always false: a provider shut down, and the record aged out under the team.
PermError vs SoftFail vs Fail: don't confuse them in reports
When you read your aggregate reports, be clear about what you see. An SPF fail (which can come from a PermError or from an unauthorized IP) doesn't have the same cause as a softfail. And above all, remember the SPF field in reports reflects alignment, not just the raw result. A source in PermError will appear as a failure; once your record is repaired, it should turn green again. That's the definitive proof the fix landed.
Frequently asked questions
Does PermError mean my mail is rejected? Not directly by SPF, but via DMARC: if SPF is in PermError and DKIM doesn't align, the message fails DMARC and suffers your policy. In practice, an uncorrected PermError eventually costs emails.
What's the difference between PermError and TempError? TempError is temporary (a passing DNS glitch) and often resolves on its own or on retry. PermError is permanent: it comes from your record and won't go away until you fix it.
Why is my SPF suddenly in PermError when it worked before? Almost always because you crossed the ten-lookup limit by adding a provider, or because an include now points to a deleted domain (void lookup). It's a threshold crossed, not a continuous degradation.
How many void lookups are allowed? Two. Beyond two DNS resolutions that return nothing, it's PermError. Hunt down dead includes and typos in domain names.
Can an analyzer fix my PermError automatically? It diagnoses it precisely, but the fix depends on the cause (cleanup, merge, syntax). A copilot like Thomas goes further: it suggests the corrected record fitted to your case.
Preventing future PermErrors
A PermError never happens without reason, and the same causes recur. Three habits prevent them for good:
- Remove a provider's
includethe day you stop using it. That's exactly what creates a void lookup when the service shuts down later, months after everyone forgot about it. - Watch your resolution count on every source you add: keep a margin before the ten-lookup limit, don't brush against it. A record at nine resolutions is a time bomb.
- Centralize SPF management. Duplicate records almost always come from two teams editing DNS independently. A single hand on the record removes the ambiguity at the root.
A quarterly check is enough to catch an include that went dead or a count creeping up — well before the PermError strikes in production and sends your invoices to spam.
More common questions
Does a PermError affect DKIM? No. DKIM is independent of SPF and has no lookup limit. If SPF is in PermError but DKIM aligns and passes, the message still passes DMARC — which is one more reason to set up aligned DKIM as a safety net.
Will receivers tell me about a PermError? Not directly, but your DMARC aggregate reports will: a source stuck in SPF failure across reports, despite being legitimate, is a strong hint to inspect your record for a PermError.
Is PermError worse than having no SPF at all? In effect, similar — both leave your domain without working SPF — but PermError is more insidious, because you believe you're protected. A none result at least makes the gap obvious. That false sense of safety is exactly why a PermError deserves prompt attention rather than a shrug.
Let Thomas diagnose and fix
A PermError always has a precise cause — you just have to find it fast, before your mail suffers. Thomas, your virtual CISO, unfolds your record, identifies the exact cause (overflow, void lookup, syntax, duplicate record), and generates the corrected SPF record for you, clean and under the ten-lookup bar.
Analyze your domain for free → or create an account to get out of PermError and stay out.
Ready to enforce DMARC?
Get to p=reject — freeRelated guides
- How to check your SPF record (and what to actually look at)
Checking your SPF isn't just confirming it exists: it's reading its syntax, resolution count, qualifier and alignment. The complete, step-by-step guide.
- SPF -all or ~all: what's the difference, and which to choose
The terminal mechanism of your SPF (-all, ~all, ?all, +all) tells receivers what to do with unlisted mail. What each one means, how they interact with DMARC, and which to publish.
- What is SPF flattening (and when to actually use it)
SPF flattening replaces your includes with the IP addresses they resolve to, to get back under the 10-lookup limit. How it works, its maintenance risks, and the alternatives.
About the author
Thomas — Thomas is the virtual CISO of DMARC.com: a copilot specialized in email authentication that walks organizations from p=none to p=reject without breaking their mail. His guides draw on real data from the DMARC Observatory and the RUA reports the platform analyzes.
