SPF PermError: Every Cause, and How to Fix Each One
A permerror is SPF telling you the record itself is broken, not just that a sender failed. Here's every documented cause and the specific fix for each.
PermError Is Not the Same Kind of Failure as Fail
It's worth separating two results that get conflated constantly: fail and permerror sound similarly bad, but they mean completely different things. A fail result means SPF evaluation completed successfully and concluded, correctly, that the sending IP is not authorized — the record worked exactly as designed. A permerror means evaluation could not be completed at all, because something about the record's structure violates the specification. One is SPF doing its job; the other is SPF being unable to do its job because of a configuration problem that exists independent of whoever happens to be sending mail at the time.
This distinction matters practically because a permerror affects every single sender checking against that domain, all the time, regardless of whether they're legitimate — it's not specific to one bad actor the way a fail result is. That makes it a considerably higher-priority problem to fix.
Every Documented Cause, and the Fix
| Cause | How to Confirm It | Fix |
|---|---|---|
| Exceeded 10-lookup limit | Recursively count every include/a/mx/ptr/exists mechanism | Remove unused vendors, flatten heavy includes, or consolidate providers |
| Exceeded 2-void-lookup limit | Identify mechanisms resolving to NXDOMAIN or empty answers | Remove or correct includes pointing at non-existent or retired domains |
| Multiple SPF records published | Query all TXT records; count how many start with v=spf1 | Merge into exactly one record; delete the duplicate(s) |
| Include/redirect target has no valid SPF record | Query the target domain's TXT records directly | Remove the mechanism, or confirm the correct current vendor hostname |
| Malformed mechanism syntax | Character-by-character review against RFC 7208 grammar | Correct the specific typo (missing colon, wrong prefix format, etc.) |
| Invalid CIDR/IP notation | Validate each ip4/ip6 entry's address and prefix length | Correct the malformed address or prefix |
| Malformed macro syntax | Check brace balancing and valid macro letters in exists:/exp= | Correct or remove the malformed macro expression |
Diagnosing Your Specific Case
Why a Record That Worked Yesterday Can PermError Today
A permerror is often not caused by anything you personally changed. Because lookup count depends partly on what included domains currently publish, a vendor adding one more nested include on their end, entirely outside your DNS zone, can push a record that was safely under 10 lookups yesterday over the limit today — with zero changes on your side. Similarly, a vendor retiring or renaming an old SPF include hostname can turn a previously valid include into one pointing at a non-existent domain, triggering a permerror through the missing-record cause. This is exactly why a one-time check isn't sufficient; SPF health needs periodic re-verification, not just a check at initial setup.
Why PermError Deserves Urgent Attention
RFC 7208 explicitly permits receiving mail servers to treat a permerror as grounds for rejecting or heavily penalizing a message, precisely because a permerror represents a domain owner's own configuration being unable to state a coherent policy at all — there's no ambiguity to resolve in the sender's favor. In practice, a permerror can silently suppress legitimate mail delivery across every vendor and sending path associated with the domain simultaneously, making it considerably higher-impact than a single vendor's fail result, and correspondingly higher-priority to catch and fix quickly.
A Walkthrough of Diagnosing a Real PermError
Say a domain's mail suddenly starts bouncing at a major receiving provider, and the bounce message references an SPF permerror. The first, fastest check is record count: query all TXT records for the domain and count how many begin with v=spf1. If it's more than one — commonly the result of a new marketing platform's setup wizard adding its own SPF record without detecting the existing one — that's the cause, and the fix is deleting the duplicate and merging any genuinely needed mechanisms from it into the single remaining record. If record count comes back clean at exactly one, the next step is a full recursive lookup count against that one record. If it resolves to 11 or more, the fix path is the same as an ordinary over-the-limit situation: trim unused vendors, flatten a heavy one, or consolidate. If the lookup count comes back comfortably under 10 and record count is fine, the remaining suspects are void lookups and syntax errors, in that order — check whether any mechanism resolves to nothing at all before assuming a typo somewhere in the record's grammar.
Why "It Worked Before" Doesn't Rule Out a New PermError
A permerror appearing on a record that was previously fine is disorienting precisely because the instinct is to assume nothing changed, so nothing should be broken. But as covered elsewhere in this series, a meaningful share of a record's lookup total lives inside vendor-controlled domains you don't administer, and those can change independently of anything you did. The same applies to the void-lookup and missing-record causes: a vendor retiring an old SPF include hostname during their own infrastructure migration, without any announcement reaching you, is entirely sufficient to turn a previously valid include into a permerror-triggering one overnight. Treat "nothing changed on my end" as an unreliable signal when diagnosing a new permerror — the actual diagnostic steps above don't depend on knowing what changed, only on checking each of the documented causes directly against the record as it stands today.
Distinguishing a PermError From a Temporary DNS Problem
It's worth briefly distinguishing permerror from temperror, a separate SPF result that looks superficially similar but means something different: temperror indicates a transient problem, like a DNS query timing out or a resolver being temporarily unreachable, that would likely resolve itself on a retry with no changes needed to the record at all. permerror, by contrast, indicates a structural problem with the record itself that will persist on every single retry until the record is actually fixed. If a validator is showing an inconsistent result — permerror on one check, a clean pass on a retry moments later with no changes made — that inconsistency itself is a signal you're actually looking at transient DNS issues rather than a genuine structural permerror, and it's worth re-running the check a few times before concluding the record itself needs editing.
A Diagnostic Decision Tree, Written Out in Full
For anyone who wants a single reference to work through rather than reading the causes as an unordered list, here's the practical order that resolves a permerror fastest, with the reasoning for each branch. Start by counting how many TXT records at the domain begin with v=spf1 — if more than one, stop here, that's the cause, and no other check matters until it's resolved, since a receiving server can't even reliably choose which record to evaluate. If exactly one record exists, next perform a full recursive lookup count against it, tallying every include, a, mx, ptr, and exists mechanism at every level of nesting — if that count exceeds 10, that's the cause, and the fix path is trimming, flattening, or consolidating as covered elsewhere in this series. If the lookup count is fine, check specifically for void lookups — any mechanism whose DNS query returned NXDOMAIN or an empty answer set — and if two or more exist, that's the cause, typically traceable to a typo'd or retired vendor domain. If none of those three structural conditions apply, the remaining likely cause is a genuine syntax error somewhere in the record's mechanism or modifier grammar, which requires a careful character-by-character comparison against RFC 7208's formal syntax definition, since this category covers everything from a missing colon to malformed macro braces to an invalid CIDR prefix.
What a Permerror Bounce Message Typically Does and Doesn't Tell You
Bounce messages referencing an SPF permerror vary enormously in how much diagnostic detail they actually include. Some receiving systems will name the specific mechanism or include chain that triggered the error; many others simply state that SPF evaluation resulted in a permanent error, with no further detail about which of the several possible causes applies. This gap between what the bounce tells you and what you actually need to know is exactly why working through the decision tree above yourself, rather than waiting for the bounce message to hand you the answer, tends to be the faster path to a fix — treat the bounce as a signal that something is wrong, not as a diagnosis of what specifically is wrong.
Preventing PermErrors From Recurring After a Fix
Fixing the immediate cause of a permerror addresses the symptom that's visible today, but the same underlying dynamics that produced it — vendor includes accumulating over time, a vendor's own infrastructure changing without notice, an easy typo slipping through an untested edit — will produce another permerror eventually unless something changes about how the record gets maintained going forward. The practical prevention measures are the same ones covered in the optimization and lookup-limit discussions elsewhere in this series: periodic recursive re-verification rather than a one-time check, testing any proposed record change against a full validator before publishing it to production DNS, and treating vendor includes as something that gets removed when a tool is retired, not just added when a tool is adopted.
PermError vs. Every Other SPF Result, Side by Side
| Result | What It Means | Whose Problem It Is |
|---|---|---|
| Pass | Evaluation completed; sending IP is authorized | N/A — working as intended |
| Fail | Evaluation completed; sending IP is explicitly not authorized | The sender's, or evidence of spoofing |
| Softfail | Evaluation completed; sending IP is probably not authorized | The sender's, treated with more leniency than fail |
| Neutral | Evaluation completed; record explicitly states no opinion | N/A — deliberate policy choice |
| None | No SPF record exists for the domain at all | The domain owner's, if authentication was expected |
| PermError | Evaluation could not complete; record is structurally broken | The domain owner's, unconditionally |
| TempError | Evaluation could not complete due to a transient DNS issue | Usually resolves itself; not a record defect |
A Second Full Diagnostic Walkthrough: The Multi-Cause Case
Real permerrors aren't always attributable to a single, clean cause — sometimes a record accumulates more than one structural problem simultaneously, and fixing the first one you find doesn't necessarily resolve the permerror if a second, independent cause is also present. Consider a domain where an audit reveals both a duplicate SPF TXT record (two separate entries both starting with v=spf1) and, once that's identified, a lookup count of 12 on the record that was intended to be canonical. Fixing only the duplicate-record issue — deleting the extra TXT entry — would still leave the domain permerroring, now purely because of the lookup count, which was masked by the more immediately obvious duplicate-record problem. This is exactly why working through the full decision tree rather than stopping at the first cause found matters: confirm each of the major structural categories (record count, lookup count, void lookup count, syntax validity) independently, rather than assuming that finding and fixing one explains the entire symptom.
Setting Up Ongoing Monitoring to Catch PermErrors Before They're Reported
Given that a meaningful share of permerror causes originate from vendor-side changes entirely outside your control, the most resilient posture is proactive monitoring rather than purely reactive troubleshooting after a bounce message arrives. This means periodically re-running a full recursive validation of your published record on a schedule — weekly is reasonable for domains with several vendor includes, monthly at minimum for simpler setups — rather than waiting for evidence of broken deliverability to prompt a check. Combined with DMARC aggregate report monitoring, which surfaces real-world SPF pass/fail patterns across your actual mail traffic, this two-pronged approach catches both the structural permerror condition itself and its practical deliverability consequences before they compound into a larger incident.
PermError Handling Differences Between SPF Libraries
Worth knowing for anyone building or evaluating mail infrastructure directly: while RFC 7208 defines permerror as a specific, standardized outcome, the open-source and commercial SPF evaluation libraries different mail servers rely on internally aren't perfectly identical in every edge case of how they detect and report the various permerror sub-causes. Most differences are minor and don't affect the overall pass/fail-style outcome, but they can affect the specific diagnostic detail available in logs or bounce messages, which is part of why working through the structural decision tree yourself, rather than trusting any single tool's specific error message wording, tends to be the more portable troubleshooting approach.
Keeping a Simple Permerror Incident Log
For domains that have experienced a permerror incident once, keeping a brief record of what happened — the specific cause, how it was found, how long it took to resolve, and what changed to prevent recurrence — tends to pay off considerably the next time something similar happens, even if the next incident has a different specific cause. Over time, this kind of log surfaces patterns (perhaps a specific vendor's includes have caused two separate incidents, suggesting that relationship deserves closer scrutiny or a flattened approach) that would be invisible if each incident were investigated and forgotten in isolation.
Related Reading in This Series
For the specific mechanics behind the most common cause, see SPF 10 Lookup Limit. For fixing a record that's genuinely too complex to maintain safely, read SPF Record Optimization. If your permerror traces back to a macro-based mechanism, SPF Macro Syntax covers the exact syntax rules. To check your record right now and see which specific cause applies, open SPF Lookup.
ToolsNovaHub tools are built and independently maintained with a focus on accurate, no-signup network and security utilities. Spotted an error? Let us know.
📋 Related Tools & Guides Comparison
| Resource | Type | Link |
|---|---|---|
| SPF Lookup | Tool | Open Tool → |
| SPF 10 Lookup Limit | Guide | Read Guide → |
| SPF Record Optimization | Guide | Read Guide → |
| SPF Macro Syntax | Guide | Read Guide → |
| DMARC Lookup | Tool | Open Tool → |