DKIM failures are usually specific and diagnosable: the verification result in the message
headers tells you which of a handful of things went wrong. This guide works through the common
ones. For each, start by reading the Authentication-Results header of an affected
message and checking the published record with our DKIM checker — between
them, they identify almost every case below.
First, read the verdict
Receivers report DKIM in the Authentication-Results header with one of a few results:
dkim=pass— the signature verified. If mail still lands in spam, your problem is elsewhere (DMARC alignment, reputation, content).dkim=fail— a signature was present and the key was retrieved, but the cryptographic check failed. Usually the message was modified, or the wrong key is published.dkim=permerror— the verifier could not even attempt the check: the record or signature is structurally broken.dkim=temperror— a transient DNS problem; usually resolves itself. Persistent temperror points at your DNS hosting.dkim=none— no signature at all. The sending system is not signing.
permerror: the record itself is broken
permerror means “permanent error — do not retry”: the verifier fetched your record
or parsed your signature and found it malformed. The usual causes:
- A corrupted
p=value. The public key is a long base64 string, and it gets damaged in transit between provider and DNS panel: line breaks pasted in, a character lost at a wrap point, invisible whitespace, or smart quotes from a word processor. The checker decodes your key and will tell you if it does not parse. - Chunking gone wrong. TXT strings hold at most 255 octets, so 2048-bit keys are stored as two strings. Some panels split correctly; some truncate; some people paste the two quoted strings with the quotes into a panel that quotes them again. Compare the record the checker retrieves against the value your provider gave you, character for character.
- Malformed tags. Missing semicolons,
V=DKIM1written into the middle of the record, or an unknownk=value.
Fix: republish the record cleanly. If the value came from a provider, copy it again directly from their console; if it is your own key, regenerate the record value with the record generator. Then re-check until the parsed-tags table looks right.
Body hash mismatch: “bh= did not verify”
The most common genuine dkim=fail. The signature contains a hash of the message
body as it left the signer (bh=); the verifier recomputes it on arrival. A
mismatch means the body changed in transit. Almost always, something legitimately modified the
message after signing:
- Mailing list software adding a subject tag or an unsubscribe footer;
- A security gateway rewriting links or attaching disclaimers;
- An internal relay re-encoding the message (line endings, character sets, MIME re-wrapping);
- Signing infrastructure hashing the message before some other component makes a final change — a footer added after DKIM signing is a classic misordering.
Fix: find the modifier and move it before signing, or stop it modifying. If
the modifier is outside your control (a recipient’s mailing list), that is expected DKIM
behaviour — it is precisely what the standard detects — and DMARC’s design accounts for it.
Two tag-level notes: the l= tag (signing only part of the body) is sometimes
suggested as a workaround, but it lets attackers append content to signed mail and several
verifiers now penalise it — avoid it. And relaxed canonicalisation
(c=relaxed/relaxed) tolerates whitespace-only changes and is the sensible
default.
No key found: signature points at a missing record
Reported variously as permerror (no key for signature) or plain fail. The
signature’s s= and d= tags name a DNS record that does not exist.
Causes, in rough order of frequency:
- The selector in the signing configuration does not match the published record name — check both ends character by character;
- The record was published at
selector._domainkey.example.com.example.com— the trailing-dot/zone-suffix mistake in DNS panels; - The record simply has not been created yet, or was deleted during a tidy-up while mail was still signing with it;
- DNS propagation has not reached the receiving resolver yet — give it the TTL.
Fix: run the exact selector through the checker. “Not found” plus NXDOMAIN in the Tech-mode resolver response confirms the name is wrong or absent. If you do not know what the signer is using, the selector finder shows what the domain actually publishes.
Multiple records at one selector
Two TXT records at the same selector name is a configuration error with a uniquely annoying symptom: intermittent failure. RFC 6376 says the result of a lookup returning multiple key records is undefined — verifiers may pick either. Mail passes at some receivers, fails at others, and the pattern changes with DNS caching. It usually happens when a key is “updated” by adding a record instead of replacing it, or when two people set up DKIM independently.
Fix: keep exactly one record per selector. If you need two keys live — say, during rotation — use two selectors; that is what they are for (selectors explained). Our checker flags this case explicitly when the sweep or lookup returns more than one DKIM record at a name.
Revoked and testing-mode keys
An empty p= tag is a deliberate signal: this key is revoked. Any
mail still signed with that selector fails. If you see a revoked selector in a sweep, the only
question is whether the revocation was intentional; if the signer still uses it, rotate
properly — here is the sequence.
A t=y flag marks the key as “in testing”: verifiers check the
signature but are told not to treat failures as significant, and some receivers treat the
whole signature as if it were absent. Testing mode is fine for a first rollout — but it is
routinely forgotten. If your DKIM has been working for weeks, remove the flag.
CNAME chains and provider delegation
Selectors published as CNAMEs into a provider’s DNS (Microsoft 365’s
selector1/selector2, Fastmail’s fm1–fm3)
add two failure modes: the CNAME target is wrong or was never created, or the provider’s
record moved and your CNAME points at the old name. Resolvers follow the chain transparently,
so the checker verifies these like any other record — if it reports Not found on a selector
your provider told you to delegate, inspect the CNAME itself at your DNS host.
temperror and slow DNS
Occasional temperror results are normal internet weather. Persistent ones mean
receivers cannot reliably resolve your record: broken nameservers, oversized responses being
dropped (a hazard with 4096-bit keys), or aggressive
rate-limiting at your DNS host. Test from several networks, and take repeated failures to your
DNS provider with timestamps.
A five-minute diagnostic routine
- Send a message from the affected system to a mailbox you control.
- Read
Authentication-Results: pass, fail, permerror, temperror or none. - Read the
DKIM-Signatureheader: noted=ands=. - Run that domain and selector through the DKIM checker in Tech mode: confirm the record exists, parses, and carries a strong key.
- Match the failure to a section above and apply the fix — then send another test.
Related guides
- What is DKIM? — how signing and verification work.
- DKIM selectors explained — record names and provider delegation.
- How to rotate DKIM keys — replace a key without new failures.
- Email DNS validator (dns.studio) — check SPF and DMARC alongside DKIM.