DKIM signature body hash did not verify: something changed the message.

This is the one DKIM failure that is not about DNS. Your key can be perfect and published correctly, and the signature still fails, because the message the receiver got is not the message that was signed. The job is finding what touched it in between.

Written by · Published 2026-09-30 · 6 min read

Where you see it

In the Authentication-Results header of a delivered message, or in a DMARC aggregate report. Gmail writes it as:

Authentication-Results: mx.google.com;
       dkim=neutral (body hash did not verify) [email protected] header.s=s1 header.b=AbCdEf12;

Other receivers say dkim=fail with a similar reason. Gmail's neutral is still a failure as far as DMARC is concerned: the signature does not count.

What it actually means

A DKIM signature has two parts. bh= is a hash of the message body, taken when the message was signed. b= is the signature itself, over a set of headers and the DKIM-Signature header (which contains bh=). A receiver checks them in that order: it hashes the body it received, compares it with bh=, and only then fetches your public key and checks b=.

"Body hash did not verify" means the first step failed. The receiver never got as far as your key. So:

What changes a body after signing

In rough order of how often I have found each one:

How to find the one you have

  1. Send the same message straight to a Gmail or Outlook mailbox, not via a list or forwarder. If DKIM passes there and fails via the other path, the other path is the cause, and it is usually the list or the gateway.
  2. Read the Received headers from the bottom up. The signature was made at the hop belonging to the d= domain. Every hop above that is a suspect. A hop belonging to a list server, a filtering service or a relay you do not control is the likely one.
  3. Compare the bodies. Save the message as sent (your application's log, or a copy sent to a mailbox you control) and as received, and diff them. The text diff checker will show an added footer or a changed encoding immediately. Remember that encoding changes show up as whole-body differences.
  4. Check the c= and l= tags in the DKIM-Signature header. c=simple/simple is fragile. l= (body length) is worse in the other direction: it lets anything be appended after the signed part, so do not use it to paper over footers.

Why it matters, and when it does not

DMARC passes if either SPF or DKIM passes and aligns with the From domain. A broken DKIM signature alone is survivable when SPF still passes and aligns. The trouble is that the paths that break DKIM (lists, forwarders) are exactly the ones that also break SPF, since the list's server is not in your SPF record. With both gone, a p=quarantine or p=reject policy sends the message to spam or refuses it. SPF vs DKIM vs DMARC explains the alignment rule; the DMARC policy guide covers when to tighten.

For mail you send yourself, fix the path. For mail to mailing lists you do not run, the list operator's fix is ARC or rewriting the From address; there is nothing you can do to your signature that survives a footer.

All guides · All tools