DKIM "body hash did not verify" and other DKIM failures: causes and fixes
"Body hash did not verify" means the message body changed after it was DKIM-signed, so the hash in bh= no longer matches. Common causes are mailing list footers, gateways adding disclaimers or rewriting links, and encoding changes. Other DKIM errors, such as no key for signature, are DNS or key problems.
On this page 8 sections
You've found dkim=fail (body hash did not verify) in a message header, or a DMARC report shows DKIM failing for a service you know is set up. DKIM failures look cryptic, but RFC 6376 gives each one a specific name, and each name points to a different cause. This guide maps the error text to the cause and the fix.
What does "body hash did not verify" mean?
A DKIM signature contains two hashes:
bh=is a hash of the body, as the sender saw it.b=is the signature over selected headers, including theDKIM-Signatureheader itself (and so the body hash).
RFC 6376 section 6.1.3 tells the receiver to compute the body hash again. "If the hash does not match, the Verifier SHOULD ignore the signature and return PERMFAIL (body hash did not verify)."
In plain terms: the body changed after it was signed. The key is fine and DNS is fine. Something between the sender's signing server and the recipient altered the content.
Receivers report it slightly differently. RFC 8601 defines dkim=fail for a signature that failed verification and dkim=neutral for signatures that couldn't be processed and "other failures not covered elsewhere," so you may see either result with the reason in brackets.
What are the different DKIM failure reasons?
RFC 6376 section 6.1 names each failure. This table lists the ones you'll actually meet:
| Reason in the header | What happened | Where to look |
|---|---|---|
body hash did not verify |
Body changed after signing | Lists, gateways, forwarders, encoding |
signature did not verify |
Signed headers changed, or the key doesn't match the private key | Subject tags, header rewrites, wrong key in DNS |
no key for signature |
Nothing published at s._domainkey.d |
Selector name, DNS host, CNAME target |
key unavailable (TEMPFAIL) |
DNS lookup didn't answer | DNS outage, timeouts |
key syntax error |
Record isn't a valid DKIM key | Broken TXT strings, stray quotes or spaces |
key revoked |
Record has an empty p= |
Old selector still in use after rotation |
inappropriate key algorithm |
Key type doesn't match the signature's a= |
Wrong record at that selector |
| Key too short (RFC 8301) | RSA key under 1024 bits | Regenerate at 2048 bits |
What causes the body to change?
Mailing lists
RFC 6377 describes exactly what lists do. "Some lists prepend or append a few lines to each message," and "changes to the body will alter the body hash computed at the DKIM Verifier." Lists that reformat MIME parts, flatten HTML or strip attachments break signatures too. Subject tags like [example] break the b= signature instead, because Subject is normally signed.
RFC 6377 concludes that a list subscriber "cannot expect signatures applied before the message was processed by the MLM to be valid on delivery." This is normal. Most list software now rewrites the From line so DMARC is judged against the list's domain, as RFC 9989 section 7.4 notes.
Security gateways and disclaimers
Anything that edits a message in transit breaks a body hash: a legal disclaimer added on the way out, an "external sender" banner, rewritten links for click protection, or an attachment replaced with a link. Microsoft's DMARC guide acknowledges this for inbound mail: if "you use an email service that modifies messages in transit before delivery into Microsoft 365," you may need to identify it as a trusted ARC sealer so modified messages don't automatically fail (Microsoft Learn).
For outbound mail, the order matters. If your own system adds a disclaimer or footer, make sure it happens before DKIM signing, not after.
Forwarders that modify mail
Plain forwarding usually leaves DKIM intact. RFC 9989 says DKIM signatures "will generally remain valid" in relay situations. But a forwarder that adds a note, rewrites the subject or re-encodes the message breaks it. Microsoft's DKIM troubleshooting lists "DKIM fails after message forwarding" with the cause "message body or headers were modified by an intermediary." See why forwarding breaks SPF and DMARC.
Encoding and line endings
RFC 6376 section 5.3 warns that messages with 8-bit characters "are subject to modification during transit, notably conversion to 7-bit form. Such conversions will break DKIM signatures." It asks signers to encode the message as quoted-printable or base64 first, and to convert bare CR or LF characters to CRLF before signing. Homegrown scripts and old applications that send mail are the usual suspects.
Simple canonicalization
DKIM's c= tag sets how strictly whitespace is compared. With simple, almost any change breaks the signature. With relaxed, the receiver ignores trailing whitespace and collapses runs of spaces, which RFC 6376 says "tolerates common modifications such as whitespace replacement and header field line rewrapping." If you control the signer, use c=relaxed/relaxed. Microsoft 365 uses relaxed as the default for both body and header canonicalization.
What causes "no key for signature"?
The receiver looked up selector._domainkey.domain from the signature's s= and d= tags and found nothing. RFC 6376 says the verifier "MUST immediately return PERMFAIL (no key for signature)." Check:
- The exact selector and domain. Read
s=andd=from the failing header. Our guide on finding a DKIM selector explains how. - A doubled domain name. Microsoft lists entering
selector1._domainkey.contoso.comin a host that appends the zone, producingselector1._domainkey.contoso.com.contoso.com. Enter onlyselector1._domainkey. - A TXT where a CNAME belongs. Microsoft 365 needs CNAMEs; Microsoft says a TXT record at that name leaves DKIM status as CnameMissing.
- Wrong CNAME target. Copy the exact target from your provider; don't build it by hand.
- Propagation. Wait out the old TTL before testing again.
How does a TXT record break a DKIM key?
A 2048-bit RSA key is longer than a single DNS TXT string can hold. RFC 8301 explains that "widely used DNS configuration software" only handles "a single 256-octet string in a TXT record, and RSA keys significantly longer than 1024 bits don't fit in 256 octets." So the key is split into several quoted strings inside one record:
s202610._domainkey.example.com. TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqh...first part..."
"...second part...IDAQAB" )
RFC 6376 section 3.6.2.2 says "strings in a TXT RR MUST be concatenated together before use with no intervening whitespace." Mistakes that break this:
| Mistake | Result |
|---|---|
| Key split into two separate TXT records | RFC 6376: with multiple records, "the results are undefined" |
Escape characters or other non-base64 text (such as \n) left inside the key |
Key no longer decodes; key syntax error or signature did not verify |
| Literal quote marks pasted into a web form | Quotes become part of the key |
| A character lost at the split point | Key decodes to the wrong value |
The -----BEGIN PUBLIC KEY----- lines left in |
Not valid base64 for p= |
Our DKIM Checker joins the strings the way receivers do, measures the key length and reports a key that doesn't decode, for example because of stray quotes or a bad split.
Is my DKIM key too short?
RFC 8301 sets the floor: signers "MUST use RSA keys of at least 1024 bits" and "SHOULD use RSA keys of at least 2048 bits." Verifiers "MUST NOT consider signatures using RSA keys of less than 1024 bits as valid." It also retired SHA-1: rsa-sha1 "MUST NOT be used for signing or verifying."
Google requires a key "of 1024 bits or longer" for mail to personal Gmail accounts and recommends 2048 bits if your DNS provider supports it (Google sender guidelines). If the checker shows 512 or 768 bits, generate a new 2048-bit key under a new selector. Our DKIM key rotation guide covers the safe order, and the DKIM Key Generator creates a key pair in your browser.
How do I troubleshoot a DKIM failure step by step?
- Get the full headers of a failing message and paste them into the Email Header Analyzer.
- Read the reason next to
dkim=inAuthentication-Results, and thes=,d=,c=andh=tags inDKIM-Signature. - If it's a key problem (no key, syntax, revoked, too short), fix DNS and check with the DKIM Checker.
- If it's a body or signature problem, compare the
Receivedheaders with your expected path. Look for a list, gateway, forwarder or disclaimer system in between. - Test the direct path. Send the same message straight to an outside mailbox. If DKIM passes there, the problem is the intermediary, not your signing.
- Check DMARC impact. If SPF still passes and aligns, DMARC can pass anyway. If not, see why DMARC fails.
Next steps
- Run the DKIM Checker on every selector you use and fix anything under 2048 bits where your provider allows it.
- Make sure footers and disclaimers are added before signing, not after.
- Use relaxed canonicalization if you control the signer.
- Publish DMARC and read the reports to see which receivers see DKIM failures; what is DMARC explains the setup.
For mail coming in to your domain, an inbound filter such as iBlockSpam screens for spam, phishing and spoofing before delivery; see how it works.
When a device or app on your network keeps breaking signatures, sending it through a relay that signs after any changes helps. iBlockSpam's outbound relay DKIM-signs mail it relays, with 500 messages per domain per month on both plans.
Browse our other SPF, DKIM and DMARC guides.
Frequently asked questions
What does "body hash did not verify" mean in DKIM?
The receiver hashed the message body it received and got a different value from the bh= tag the sender signed. Something changed the body in between: a footer, a disclaimer, rewritten links, re-encoding or a broken line ending. RFC 6376 tells verifiers to ignore that signature and return a permanent failure.
Does a DKIM failure mean the email is fake?
Not on its own. Legitimate mail often fails DKIM after a mailing list or gateway changes it. A failed signature is treated as if there were no signature. What matters for spoofing is DMARC: whether any SPF or DKIM pass aligns with the From domain.
Can a mailing list footer break DKIM?
Yes. RFC 6377 says lists that prepend or append lines to each message change the body hash and make existing signatures unverifiable. Subject tags such as [listname] break the signature too, because Subject is normally signed. Most list software now rewrites From to avoid DMARC failures.
Should I use the DKIM l= tag so footers don't break my signature?
No. The l= tag limits how much of the body is signed, but RFC 6376 warns it lets an intermediary append content that benefits an attacker, and RFC 6377 says it doesn't work for MIME messages and discourages its use. Sign the whole body and rely on DMARC-aware handling instead.
Is a 1024-bit DKIM key still accepted?
Yes. RFC 8301 says signers must use RSA keys of at least 1024 bits and should use 2048 bits, and verifiers must not accept keys under 1024 bits. Google requires at least 1024 bits for personal Gmail accounts and recommends 2048. Move to 2048 when your DNS host supports it.
Sources
- RFC 6376: DKIM Signatures, section 6.1 (Verifier actions)
- RFC 6377: DKIM and Mailing Lists
- RFC 8301: Cryptographic Algorithm and Key Usage Update to DKIM
- RFC 8601: Message Header Field for Indicating Message Authentication Status
- Microsoft Learn: How to use DKIM for email in your custom domain
- Microsoft Learn: Set up DMARC to validate email in Microsoft 365
- Gmail Help: Email sender guidelines
- RFC 9989: DMARC, section 7.4
See how your domain measures up
Run a free Email Health Check: MX, SPF, DKIM, DMARC and transport security in one scan, with the raw records shown. No sign-up.
Keep reading
How to rotate DKIM keys without breaking email
How often to rotate DKIM keys, which key length to use, how to name selectors, and how to rotate in Microsoft 365, Google Workspace and on your own server.
9 min read SPF, DKIM & DMARCWhy email forwarding breaks SPF and DMARC, and how ARC helps
Why forwarding and mailing lists break SPF and sometimes DKIM, how that fails DMARC, and how SRS, ARC and trusted ARC sealers in Microsoft 365 help fix it.
9 min read SPF, DKIM & DMARCHow to find a domain's DKIM selector, and check its key
Find a DKIM selector from the s= tag in an email header, see the selectors Microsoft 365, Google Workspace and common senders use, then check the key.
8 min read