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.

📅 Published August 2026· ⏳ 16 min read· ✍️ ToolsNovaHub Editorial Team
🛠️ Related tool: Open SPF Lookup →

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.

ToolsNovaHub Pro Tip
Whenever you see a permerror, check lookup count, void lookup count, and record count as three separate things before assuming it's a syntax typo. The vast majority of real-world permerrors trace back to one of those three structural limits, not a spelling mistake.
⚠️
Common Beginner Mistake
Adding a second SPF TXT record instead of editing the existing one, often because a new tool's setup wizard adds its own record without checking for an existing one first. This alone is enough to break SPF for the entire domain.

Every Documented Cause, and the Fix

CauseHow to Confirm ItFix
Exceeded 10-lookup limitRecursively count every include/a/mx/ptr/exists mechanismRemove unused vendors, flatten heavy includes, or consolidate providers
Exceeded 2-void-lookup limitIdentify mechanisms resolving to NXDOMAIN or empty answersRemove or correct includes pointing at non-existent or retired domains
Multiple SPF records publishedQuery all TXT records; count how many start with v=spf1Merge into exactly one record; delete the duplicate(s)
Include/redirect target has no valid SPF recordQuery the target domain's TXT records directlyRemove the mechanism, or confirm the correct current vendor hostname
Malformed mechanism syntaxCharacter-by-character review against RFC 7208 grammarCorrect the specific typo (missing colon, wrong prefix format, etc.)
Invalid CIDR/IP notationValidate each ip4/ip6 entry's address and prefix lengthCorrect the malformed address or prefix
Malformed macro syntaxCheck brace balancing and valid macro letters in exists:/exp=Correct or remove the malformed macro expression

Diagnosing Your Specific Case

1️⃣
Check Record Count First
Query all TXT records and confirm exactly one starts with v=spf1 — this is the fastest check and rules out the second most common cause immediately.
2️⃣
Count Lookups Recursively
Trace every include and redirect, including their own nested mechanisms, and tally the real total against the 10-lookup ceiling.
3️⃣
Check for Void Lookups
Identify any mechanism resolving to nothing at all — a typo'd or retired vendor domain is the usual culprit here.

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

ResultWhat It MeansWhose Problem It Is
PassEvaluation completed; sending IP is authorizedN/A — working as intended
FailEvaluation completed; sending IP is explicitly not authorizedThe sender's, or evidence of spoofing
SoftfailEvaluation completed; sending IP is probably not authorizedThe sender's, treated with more leniency than fail
NeutralEvaluation completed; record explicitly states no opinionN/A — deliberate policy choice
NoneNo SPF record exists for the domain at allThe domain owner's, if authentication was expected
PermErrorEvaluation could not complete; record is structurally brokenThe domain owner's, unconditionally
TempErrorEvaluation could not complete due to a transient DNS issueUsually 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.

Reviewed by: ToolsNovaHub Editorial Team📅 Last updated: August 2026📜 Sourced from: RFC 7208

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

ResourceTypeLink
SPF LookupToolOpen Tool →
SPF 10 Lookup LimitGuideRead Guide →
SPF Record OptimizationGuideRead Guide →
SPF Macro SyntaxGuideRead Guide →
DMARC LookupToolOpen Tool →
Try it yourself — 100% free
🚀 Open SPF Lookup

🔗 More Guides

FAQ

It means the SPF record itself, as published, is malformed or violates one of the specification's structural limits in a way that makes it impossible to evaluate correctly — not that a particular sender failed authorization.
No, they're fundamentally different results. fail means the record was evaluated successfully and the sending IP is explicitly not authorized. permerror means evaluation couldn't even be completed correctly because of a problem in the record itself.
Exceeding the 10-lookup limit is the single most common cause in practice, typically from accumulating too many vendor includes over time without ever auditing or trimming the record.
Yes, publishing multiple TXT records that both start with v=spf1 is explicitly invalid per RFC 7208 and results in a permerror, since the specification requires exactly one SPF record per domain.
Query all TXT records for your domain directly and check how many begin with v=spf1 — legitimate configurations sometimes have multiple unrelated TXT records for other purposes (domain verification, DKIM, etc.), but only one should ever start with the SPF version tag.
Yes, any structurally invalid mechanism, modifier, or qualifier — a missing colon after include, an unrecognized mechanism name, unbalanced macro braces — causes a permerror since the record can't be parsed correctly.
Yes, both are structural evaluation failures resulting in the identical permerror outcome, even though they're triggered by different specific conditions (too many total lookups vs. too many empty-result lookups).
That specific mechanism cannot be evaluated as required and results in a permerror, since include and redirect both mandate that their target actually publish a valid record.
Yes, an invalid CIDR notation, malformed address, or incorrect prefix length is a syntax error in the mechanism and causes a permerror during parsing.
Generally no, order affects which mechanism matches first, not whether the record is structurally valid — one specific exception is content placed after a redirect= modifier, which is functionally dead but not itself a syntax error.
Use a validator that recursively resolves every include and explicitly reports lookup count, void lookup count, record count, and syntax validity separately, rather than just reporting a final pass/fail/permerror without explanation.
Not universally — RFC 7208 leaves the exact disposition up to the receiving server's local policy, but it explicitly permits treating permerror as grounds for rejection, and many providers do exactly that, making it a high-risk result to leave unresolved.
Yes, this is extremely common — adding one more include to a record that was already close to the 10-lookup ceiling, or that already had two void lookups, can push it over without any other change to the record.
Yes, always test the exact new record text with a full recursive validator before publishing it to your DNS zone, rather than publishing first and checking after propagation.
No, SPF evaluation is domain-specific to whatever exact domain appears in the envelope sender being checked; a permerror on one domain's record has no direct effect on a different domain's own separately published record.