All posts
June 15, 20266 min read

DKIM signature did not verify: the causes, in order of likelihood

A message arrives and the headers say dkim=fail or, in a DMARC report, the DKIM result is fail for your domain. DKIM is more deterministic than SPF: a signature either matches or it does not, and when it does not, there is a short list of concrete reasons. Work through them in order and you will find it.

How DKIM verification works in one paragraph

The sending server hashes parts of the message (selected headers and the body), encrypts that hash with a private key, and attaches it as a DKIM-Signature header. That header names a domain (d=) and a selector (s=). The receiver fetches the matching public key from DNS at <selector>._domainkey.<domain>, uses it to verify the signature, and independently re-hashes the message to confirm nothing changed. If either the signature check or the body hash check fails, DKIM fails.

That gives exactly four places it can go wrong.

1. The public key is missing or wrong in DNS

The most common cause. The receiver looks up <selector>._domainkey.<domain> and finds nothing, finds a malformed record, or finds a key that does not match the private key that signed the message. This happens when DKIM was set up at the provider but the DNS record was never published, was published on the wrong host, or was published with the key split or mangled across TXT chunks.

Check the exact selector named in the DKIM-Signature header (s=) and confirm a valid key exists at that location. The DKIM generator builds and validates the record format so you can compare what should be published against what is actually in DNS. To see the raw selector and signing domain from a real message, paste the headers into the email header analyzer.

2. The body or signed headers changed in transit

DKIM verifies a hash of the body and of specific headers. If anything modifies them after signing, the hash no longer matches and you get a body hash mismatch — a distinct, telling failure. Causes include a mailing list that appends a footer, an appliance that rewrites links or adds a disclaimer, or a forwarder that re-encodes the body. The c= tag controls canonicalization (relaxed tolerates whitespace and case changes; simple does not), and a too-strict canonicalization makes harmless reformatting break the signature.

If DKIM passes on direct delivery but fails after passing through a list or gateway, this is your cause. The signing is fine; something downstream is editing signed content.

3. The wrong selector, or a rotated key

If you rotated keys and published a new selector but the sending system is still signing with the old one (or vice versa), the receiver fetches a key that does not correspond to the signature. During rotation, keep both selectors published until all in-flight mail has drained, then retire the old one.

4. The key is too short or the algorithm is weak

Receivers increasingly reject DKIM keys shorter than 1024 bits, and 2048-bit RSA is the current expectation. A 512-bit key, or a deprecated signing algorithm, can be treated as a failure regardless of whether the math checks out. If your DKIM was set up many years ago and never rotated, regenerate it at 2048 bits.

Confirm the fix

After correcting the record, send a test message to an address you control and read the authentication results in the email header analyzer: you want dkim=pass with d= equal to your domain so it also aligns for DMARC. Then regenerate or re-validate your published record with the DKIM generator to check yours.