SPF PermError: what it means and how to fix it
By Thomas · virtual CISO · July 07, 2026
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 the record is impossible to evaluate correctly. To the receiving server, it's almost as if the SPF didn't exist — with, on top of that, a negative signal for DMARC. The trap is that the mail is perfectly legitimate; only the 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
Placing the PermError means knowing 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 the record is fixed.
Why a PermError is dangerous
A PermError doesn't "block" mail directly, but it strips the 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 the policy in force (quarantine, reject), it goes to spam or gets refused. In other words: a broken record can send a domain's 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. Past ten, 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 — each mechanism has to be unfolded 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. A careful re-read catches some of them; safer still, a tool validates the syntax.
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 along the way that ten resolutions aren't exceeded.
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
A domain has just tipped into PermError without warning. The team swears it "changed nothing." Unfolding it tells another story. 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, the count reaches eleven resolutions: the ten-lookup limit is also exceeded. Two stacked PermError causes, which explains why an "eyeball" diagnosis had failed.
The fix comes in two steps. First, removing 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, Mailchimp (servers.mcsv.net) moves 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: not to be confused in reports
Reading the aggregate reports calls for clarity about what they show. 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, the SPF field in reports reflects alignment, not just the raw result. A source in PermError shows up as a failure; once the 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 the policy in force. 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 the record itself and won't go away until it's fixed.
Why is my SPF suddenly in PermError when it worked before? Almost always because the ten-lookup limit was crossed 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. Dead includes and typos in domain names are what to hunt down.
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 the case at hand.
Preventing future PermErrors
A PermError never happens without reason, and the same causes recur. Three habits prevent them for good:
- Removing a provider's
includethe day it stops being used. That's exactly what creates a void lookup when the service shuts down later, months after everyone forgot about it. - Watching the resolution count on every source added: keeping a margin before the ten-lookup limit, not brushing against it. A record at nine resolutions is a time bomb.
- Centralizing 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 invoices to spam.
One more habit worth adopting: testing after every DNS change, not just on a schedule. The PermError in the example above went unnoticed precisely because nobody re-evaluated the record when the old provider was decommissioned — the change that broke SPF didn't look like an SPF change at all. Treating any modification that touches sending infrastructure (a provider added or dropped, a migration, a subdomain created) as a trigger for a quick SPF re-check costs seconds and catches the regression the day it's introduced, when the cause is still obvious, instead of six months later when nobody remembers what changed.
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 the DMARC aggregate reports do: a source stuck in SPF failure across reports, despite being legitimate, is a strong hint to inspect the record for a PermError.
Is PermError worse than having no SPF at all? In effect, similar — both leave the domain without working SPF — but PermError is more insidious, because it comes with the belief of being 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.
Thomas diagnoses and fixes
A PermError always has a precise cause — it just has to be found fast, before the mail suffers. Thomas, the virtual CISO, unfolds the record, identifies the exact cause (overflow, void lookup, syntax, duplicate record), and generates the corrected SPF record, clean and under the ten-lookup bar.
Analyze a domain for free or create an account to leave PermError behind and stay out.
Related guides
- What is SPF, and how does it authorize sending servers?
A plain-English guide to SPF (RFC 7208): what it is, the DNS record, the include/ip4/a/mx mechanisms, the 10-lookup limit, and why SPF alone isn't enough.
- SPF for Microsoft 365 and Google Workspace: the setup that works
SPF for Microsoft 365 and Google Workspace, separately or together, without busting the 10-lookup limit. The right includes, traps, third parties.
- SPF macros and the exists mechanism: going beyond the 10-lookup limit
SPF macros with the exists mechanism authorize unlimited IPs in one DNS lookup, the only real way past the limit of 10. How it works, what it costs.
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.
