Email deliverability, DNS, SPF/DKIM/DMARC
Fix SPF Syntax Error in Your TXT Record
Typos, missing colons, smart quotes, or unknown mechanisms break SPF parsing and produce PermError. Validate syntax before republishing the TXT record.
What's happening
RFC 7208 Section 5 specifies an exact grammar for SPF records. The record must begin with v=spf1, followed by space-separated mechanisms (ip4:, ip6:, include:, a, mx, ptr, exists:, all) each prefixed with an optional qualifier (+, -, ~,?), and may end with optional modifiers (redirect=, exp=). Any deviation from this grammar yields PermError.
Common syntax problems are subtle: a missing colon after include, a smart quote pasted from a vendor PDF, an unrecognized mechanism like "includes:" instead of "include:", or a stray non-breaking space. The record looks correct in a casual visual scan but fails strict tokenization.
A subset of receivers tolerate minor errors (silently ignoring an unknown mechanism), but most modern implementations are strict and return PermError. Mixed behavior is the worst outcome — some receivers pass your mail, others reject it, and the inconsistency is hard to diagnose without DMARC aggregate reports.
Why it matters
Strict receivers like Gmail and Microsoft 365 produce spf=permerror on every message and apply the full reputation penalty. DMARC SPF alignment fails on every message, leaving DKIM as the only line of defense.
If a syntax error is introduced during a routine DNS change, deliverability degradation can be sudden — yesterday's reputation collapses today, and Mail-Tester scores drop by 1.5-2.0 points immediately.
Phishing and spoofing protection is also lost. SPF cannot block unauthorized senders if the record is unparseable — receivers default to no policy, and attackers can spoof your envelope-from with no friction.
Common causes
- Smart quotes from copy-pasting from a vendor portal or PDF.
- Misspelled mechanism ("includes:" or "include" without the colon).
- Trailing newline or non-breaking space inside the TXT value.
- Unknown qualifier such as "!all" instead of "-all".
- Domain-name in include: that does not resolve (no TXT record at the target).
- Missing space between mechanisms (ip4:1.2.3.4ip4:5.6.7.8).
Detect this on your site
Run a quick scan with the Email Checker. The tool surfaces this exact issue with the records and context needed to apply the fix below.
Open Email CheckerHow to fix it
- 1
Read the exact PermError reason
Run the CheckFast Email Checker or MXToolbox SPF Lookup. Both report the parse position where the error occurred — for example "unexpected token at character 47". That is the first thing to fix.
- 2
Re-type the record from scratch
Open a plain text editor (vim, nano, VS Code with smart-quote autocorrect off). Type v=spf1 followed by each mechanism. Do not paste from PDFs, vendor portals, or rich-text emails — they introduce smart quotes and zero-width characters.
- 3
Validate every mechanism prefix
Each mechanism must start with one of: +, -, ~,?, or no qualifier (defaults to +). The mechanism keyword must be one of: all, include, a, mx, ip4, ip6, exists, ptr (deprecated). Anything else is a syntax error. Modifiers redirect= and exp= go at the end.
- 4
Confirm domain targets resolve
For every include:domain, exists:domain, and redirect=domain, run dig +short TXT domain. If the target does not return a TXT record (or returns NXDOMAIN), the SPF lookup will produce PermError. Remove broken includes or fix the target.
- 5
Republish with TTL 300
Update the TXT record at your DNS provider with the corrected value. Set TTL to 300 seconds during change windows so corrections propagate fast. Verify with dig +short TXT example.com.
- 6
Run a Mail-Tester probe
Send a test message to a fresh mail-tester.com address. The SPF row should read pass. If it still says permerror, run the Email Checker again — it will pinpoint the new error position.
Example
; Wrong — smart quotes and missing colon example.com. IN TXT “v=spf1 includes_spf.google.com ~all” ; Right — straight quotes, correct mechanism example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
Two of the most common SPF syntax errors in one example.
Frequently asked
No. RFC 7208 grammar does not allow comments. Anything that is not a recognized mechanism qualifier or modifier is a syntax error. Document context outside DNS — a runbook a ticket or a wiki page.
Mechanism names (include a mx all) are case-insensitive per RFC 7208. Domain names inside mechanisms follow normal DNS case-insensitivity. The version tag must be lowercase v=spf1 — not V=SPF1 — for some implementations.
DNS TXT records support multiple character-strings of up to 255 octets each automatically concatenated by resolvers. Most DNS providers handle the chunking transparently. If your provider does not manually split into multiple quoted strings on the same record (one record multiple strings).
Related fixes
Email deliverability, DNS, SPF/DKIM/DMARC
Fix SPF PermError on Inbound Authentication Checks
Email deliverability, DNS, SPF/DKIM/DMARC
Fix Multiple SPF Records Causing PermError on Receivers
Email deliverability, DNS, SPF/DKIM/DMARC
Fix SPF Too Many DNS Lookups (PermError 10-Limit)
Email deliverability, DNS, SPF/DKIM/DMARC
Fix Missing SPF Record on Your Sending Domain
Email deliverability, DNS, SPF/DKIM/DMARC
Fix Missing DMARC Record on Sender Domain