DKIM troubleshooting

The failures you will actually meet — what each one means, how to confirm it, and how to fix it

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:

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:

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:

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:

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 fm1fm3) 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

  1. Send a message from the affected system to a mailbox you control.
  2. Read Authentication-Results: pass, fail, permerror, temperror or none.
  3. Read the DKIM-Signature header: note d= and s=.
  4. Run that domain and selector through the DKIM checker in Tech mode: confirm the record exists, parses, and carries a strong key.
  5. Match the failure to a section above and apply the fix — then send another test.

Related guides