DKIM Signature Verification Failed: Causes and Fixes

iagnose DKIM verification failures, from missing selector records and revoked keys to body hash mismatches, relay modifications and key rotation.

A published DKIM record is only one part of a working signature. A receiver also needs to find the right public key, calculate the message's body hash, and verify the cryptographic signature against the signed headers. A failure at any of those steps can produce dkim=fail or another unsuccessful DKIM result.

The fastest way to troubleshoot is to start with the received message, not the DNS settings you expected the sender to use. Its headers identify the signing domain and selector that were actually used.

Start with the receiver's result

Open the original source of a message that failed. Find the Authentication-Results header added by the receiving system you trust. For example:

Authentication-Results: mx.receiver.example;
    dkim=fail (body hash did not verify) header.d=example.com header.s=s1;
    spf=pass smtp.mailfrom=bounce.example.com;
    dmarc=pass header.from=example.com

This is an illustrative result, not a real test message. It tells us three different things:

  • The receiver tried to verify a DKIM signature for example.com, selector s1, and the body hash did not match.
  • SPF passed using bounce.example.com.
  • DMARC still passed because SPF passed and its domain aligned with the visible From: domain, example.com.

A DKIM failure does not automatically mean a DMARC failure. Nor does dkim=pass guarantee DMARC success: a valid signature from an unrelated signing domain may be unaligned. See our DMARC alignment troubleshooting guide for that separate check.

Be careful about the source of Authentication-Results: an untrusted sender can insert misleading headers. Use results generated by the mailbox provider or receiving server you control.

Read the DKIM-Signature header

A signed message may contain a header resembling this:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
    d=example.com; s=s1; h=from:to:subject:date;
    bh=<base64-body-hash>; b=<base64-signature>

The values in angle brackets are explanatory placeholders, not valid DKIM signature data.

Tag What it tells you
d= Signing domain. The public key is looked up beneath this domain.
s= Selector: the key name chosen by the sending system.
a= Signing algorithm, such as rsa-sha256.
c= Header and body canonicalization rules; here, relaxed for both.
h= Header fields covered by the signature.
bh= Hash of the canonicalized message body.
b= Cryptographic signature over the selected headers and DKIM-Signature field.

For d=example.com and s=s1, the DNS name to inspect is:

s1._domainkey.example.com

Do not guess a selector from your provider's name. Read the exact s= value from the failed message. If a message contains multiple DKIM-Signature headers, inspect each one: one failed signature does not prove every signature failed.

1. The public key cannot be found

A receiver generally queries DNS for a TXT record at the selector name. Try:

dig +short TXT s1._domainkey.example.com

Some providers delegate the selector through a CNAME instead of asking you to publish the DKIM public key directly. If the TXT query returns nothing, check the alias too:

dig +short CNAME s1._domainkey.example.com

If there is a CNAME, follow it and check the provider's destination. If there is neither a usable TXT key nor a working CNAME, the signature cannot be verified using that selector.

Common causes include an incorrect DNS hostname, a selector copied from an old configuration, a key deleted during rotation, or a record published in the wrong DNS zone. For example, some DNS control panels automatically append the zone name; entering the full hostname can accidentally create s1._domainkey.example.com.example.com.

Fix: Compare the message's d= and s= values with the sending platform's active configuration. Restore the appropriate record or correct the delegation. Then send a new test message. DNS propagation and caching can delay when receivers see a change.

An unreachable DNS server or temporary lookup failure is different from a missing record. A receiver may report a temporary DKIM error rather than a permanent verification failure. Check DNS availability and retry before rotating keys.

2. The public key is present but unusable

A DNS answer is not necessarily a valid DKIM key. For an RSA key, a selector TXT record typically looks like this:

v=DKIM1; k=rsa; p=<base64-public-key>

Again, the placeholder must be replaced with the actual key supplied by your signer. The most useful checks are:

  • Is p= populated? An empty p= means the key has been revoked, not that the field is optional.
  • Is the data complete? A long TXT record may be displayed as several quoted strings in one DNS TXT response. That is normal; the verifier concatenates those strings. Separate, conflicting TXT resource records are not the same thing.
  • Does the key match the signing system? A public key from a previous rotation cannot verify a signature made with a different private key.
  • Does the algorithm match? The signature algorithm, DNS key type, and verifier's supported algorithms must be compatible.

For RSA, RFC 8301 requires verifiers not to accept keys shorter than 1024 bits and recommends that signers use at least 2048 bits. It also prohibits rsa-sha1 for signing or verifying. RFC 8463 defines ed25519-sha256 as an additional DKIM signing algorithm; verify support in your actual mail path rather than assuming all systems use RSA.

You can check the DNS record format with the DeliverSight DKIM checker. A valid-looking DNS key still cannot establish that the message's signature verifies: that requires the signed message and the correct public key together.

3. The body hash does not match

A result such as body hash did not verify means the verifier's calculation over the received, canonicalized body does not match the bh= value created when the message was signed.

Typical causes are changes after signing:

  • A mailing list adds a footer to the body.
  • A gateway rewrites URLs or modifies HTML.
  • A relay changes MIME encoding or reconstructs message parts.
  • A downstream system appends a disclaimer or tracking content.

The fix is not to regenerate the DNS key. Identify the hop changing the message. Compare a copy captured immediately after DKIM signing with the message received at the destination. If you control the sending pipeline, perform content modification before signing, with DKIM signing as late as practical.

The c= tag matters, but it has limits. relaxed/relaxed tolerates some whitespace and formatting differences; it does not make arbitrary body edits safe. Switching from simple to relaxed will not reliably fix a gateway that adds a paragraph or rewrites URLs.

Plain forwarding, by itself, does not necessarily break DKIM. Forwarding often breaks SPF because the connecting IP changes, while DKIM can survive if the signed content and relevant headers are left intact. Investigate what the intermediary actually changed.

4. The body hash matches, but the signature still fails

The bh= check and the b= cryptographic signature check are different operations. When the body hash is correct but signature verification fails, investigate the signed headers and the key pair.

For example, a gateway may rewrite a Subject: field covered by h=, or a sender may publish a new public key while its mail servers continue using the old private key. Changes to signed header fields outside the canonicalization allowances can invalidate the signature even when the body is untouched.

A useful way to isolate the issue is to compare one message before and after the suspected relay. Preserve raw MIME bytes where possible rather than copying rendered text from a mail client. If all newly signed messages fail immediately after a key change, check the signer-to-DNS key pairing before blaming intermediaries.

5. Key rotation removed a selector too early

A normal rotation may briefly have two selectors in service:

s1._domainkey.example.com   # previous key
s2._domainkey.example.com   # new key

The sending system starts using s2, but messages signed earlier with s1 may still be in transit or queued for retry. Deleting s1 immediately can make those older messages unverifiable at their eventual destination.

A safer rotation sequence is to publish the new key, confirm it can be resolved, change the signer to the new selector, and retain the old key long enough for already-signed mail to clear the delivery path. Set that overlap according to your sending platform's retry and queue lifetimes, not an arbitrary universal timer.

After the transition, remove the old record according to your key-management policy. If the old private key was compromised, revocation may be urgent and the trade-off is different.

6. A signature has expired

DKIM can include an optional x= expiration timestamp. If a receiver verifies the message after that time, the signature is expired. This can happen when a message is delayed in a queue longer than expected or when the signer uses an overly short expiry period.

Inspect x= together with the signing time t= when present, the receiving server's clock, and the actual delivery delay. Here t= is the DKIM signature timestamp, not the DMARC testing flag of the same name in a DNS policy record.

If expired signatures recur, investigate queue delays and the signer's expiry settings. Do not increase expiry times blindly if you use them for a deliberate security policy.

A practical diagnosis table

Receiver observation First place to look Likely next action
dkim=none Missing DKIM-Signature header Enable signing for the actual sending service.
Key not found for d= / s= Selector TXT and CNAME records Correct the selector, DNS zone or delegation.
Key revoked / malformed DKIM TXT p= and key syntax Restore a valid active key record.
DNS lookup temporarily unavailable DNS response and authoritative servers Repair DNS availability; retry verification.
Body hash mismatch Changes to MIME body after signing Compare pre- and post-relay messages.
Signature verification mismatch Signed h= headers and key pair Check header rewriting and signer/key rotation.
DKIM passes but DMARC fails d= versus visible From: domain Check DKIM alignment or aligned SPF.

Receiver wording varies; dkim=fail, permerror and temperror are not interchangeable labels across all implementations. Read any explanatory text and the raw message alongside the summary status.

Verify the fix using a freshly sent message

After making a change, do not stop when the DNS checker turns green.

  1. Send a new message from the affected application or provider. A test from a different sender can hide a service-specific problem.
  2. Inspect the received DKIM-Signature header. Confirm the active d= and s= are the ones you configured.
  3. Check the receiving system's Authentication-Results for dkim=pass on the intended signature.
  4. Compare the verified d= domain with the visible From: domain when you also need DMARC alignment.
  5. Repeat for other sending paths that use the same domain: marketing, transactional, support, and any self-hosted mail servers.

For a quick DNS lookup, use the DKIM checker. To inspect authentication on a message you actually send, run a DeliverSight email test. One clean message confirms that particular path worked; it does not prove all of a domain's mail is correctly signed.

Technical references