SPF record is empty or malformed
An SPF TXT record exists on the sending domain but contains no valid mechanisms, has syntax errors, or omits the required `v=spf1` version tag.
Receivers evaluating SPF treat a malformed record as permerror under RFC 7208, which under most DMARC policies results in rejection or quarantine. DMARC alignment via SPF becomes impossible, pushing all authentication weight onto DKIM alone. Expect sharp inbox placement drops at Google, Microsoft, and Yahoo until the record is corrected.
What causes it
- A TXT record was created with
v=spf1as the only content, with no mechanisms (include:,ip4:,a,mx) and noallqualifier. - A typo in the version tag such as
v=spf 1,v=SPF1, orspf1— SPF parsers require the literal lowercase tokenv=spf1followed by a space. - DNS management UI split the record across multiple TXT strings without proper quoting, producing concatenated garbage like
v=spf1include:_spf.google.comwith no separator. - Copy/paste from a document introduced smart quotes, non-breaking spaces, or trailing commas that are illegal in SPF syntax.
- An include target was removed or renamed (e.g. provider changed its SPF host), leaving behind a stub like
v=spf1 include: ~allwith an empty argument.
How to fix it
Dump the current record and inspect it byte-for-byte
Use dig with +short to confirm exactly what the authoritative nameserver returns. Watch for multiple quoted strings — they are concatenated at evaluation time, so a missing space between them produces a malformed record.
dig +short TXT example.com | grep spf1 Validate syntax against an SPF parser
Do not eyeball the record. Run it through a strict parser that reports mechanism-level errors, not just lookup counts. The pyspf reference implementation and checkdmarc both surface malformed tokens and empty includes.
pip install checkdmarc && checkdmarc example.com Rewrite the record with required elements
A valid SPF record must start with v=spf1, list at least one authorization mechanism, and end with an all qualifier. Use -all for strict enforcement or ~all while rolling out. Replace the TXT record in a single flat string — do not let the registrar UI split tokens.
example.com. 3600 IN TXT "v=spf1 include:_spf.google.com include:spf.postmarkapp.com -all" Verify from an external resolver and wait for TTL rollover
After publishing, query from a resolver outside your network to confirm propagation. Then re-run your SPF validator and send a test to check-auth@verifier.port25.com or similar to confirm receivers return spf=pass.
dig @1.1.1.1 TXT example.com +short Fixed it? Run a fresh test to confirm.
Test my inbox →