- Zen IT Technologies
- Technical notes
- When DKIM passes at the sender and fails at the receiver
When DKIM passes at the sender and fails at the receiver
Jonny Flaks, Founder & Principal Architect
Technical note in Email Deliverability
A message leaves correctly signed. It arrives failing authentication. Nothing in between is misconfigured in any obvious way, and the sending platform reports success.
One common cause is a body hash failure: something changed the message after it was signed in a way the selected canonicalization does not normalize away.
What the signature covers
A DKIM signature covers a selected set of headers and a cryptographic hash of the canonicalized message body, carried in the signature itself. At the receiving end, the verifier canonicalizes the message according to the mode named in the signature, recomputes the body hash and compares it with the signed value. Any change that alters the canonicalized body changes that hash. A change to one of the signed headers can invalidate the header signature separately. The key can be fine, the DNS record can be fine and the selector can be fine while the message that arrived is no longer the message representation that was signed.
What modifies a body in transit
Most of these are systems working exactly as intended:
- A mail gateway or security product appending a disclaimer, a confidentiality footer, or an external-sender banner.
- A link-rewriting product replacing URLs for click protection or threat scanning.
- A mailing list adding a footer or a subject tag.
- A relay re-encoding content transfer encoding, or re-wrapping long lines to fit line-length limits.
- An anti-spam layer inserting or normalizing headers that were included in the signed header list.
Any of these can break DKIM when it changes the canonicalized body or one of the signed headers. Some whitespace-only changes may be absorbed by relaxed canonicalization; substantive body edits are not.
Why nobody notices
Because policy usually still passes.
DMARC passes if either SPF or DKIM passes with a domain aligned to the one in the visible From header. If SPF passes and aligns, the overall DMARC result is a pass even if the DKIM signature is broken. That failure can therefore remain hidden inside an otherwise successful DMARC result; final delivery is still a separate receiver-policy decision.
It surfaces later, and indirectly. Forwarding is the clearest case: it commonly breaks SPF alignment, which leaves DKIM as the only mechanism that can carry DMARC, so a domain with a permanently failing signature is depending on the one check forwarding tends to defeat. And when policy is eventually tightened to enforcement, delivery drops for reasons that appear to have no recent cause.
The diagnosis is not in the sending platform's dashboard, which reports what it signed. It is in a raw message pulled from a mailbox at another provider, where the authentication results header states the failure reason directly.
Signing in the right place
The rule is simple to state: sign last, at the final point of egress. Whatever component is the last to touch the message body is the component that should be applying the signature.
If a gateway modifies the message body, for example by adding a legal footer or rewriting outbound links, it should apply the final DKIM signature after those changes. Its signing domain must align with the domain in the visible From header for DKIM to satisfy DMARC alignment. A gateway that signs with its own vendor domain can produce a perfectly valid DKIM signature, but that signature does not contribute an aligned DKIM pass to DMARC.
Multiple DKIM signatures are permitted, and a message carrying two is fine. For DMARC, one valid DKIM signature whose signing domain aligns with the visible From domain is sufficient on the DKIM side. This is the clean answer when an upstream platform insists on signing and a downstream gateway must modify afterwards: let both sign, and ensure the final aligned signature is applied after the last body-changing step.
Two details worth knowing
Canonicalization. DKIM specifies canonicalization separately for headers and for the body, using the modes simple and relaxed.
For the body, relaxed removes trailing whitespace from lines, collapses runs of spaces and tabs within a line, and normalizes empty lines at the end. It does not remove line boundaries, so rewrapping a line changes the canonicalized body and can change the body hash. simple preserves the body much more literally, apart from the end-of-body treatment defined by DKIM.
For headers, relaxed is different: it lowercases the field name, unfolds continuation lines and normalizes whitespace around the field value. That is where header folding differences can be tolerated. simple keeps the signed header representation much closer to what was originally signed.
The important distinction is not "strict versus forgiving". It is whether a downstream change survives the exact header and body canonicalization modes named in the signature.
The body length tag. DKIM has an optional body-length tag that limits the signed body to the first N canonicalized octets. It can appear to solve the appended-footer problem because content added after that boundary does not change the signed portion. The trade-off is serious: additional content can exist outside the signed body while the original signature still validates. For ordinary organizational mail, do not use this as a workaround for downstream body modification; fix the signing point instead.
Verification worth doing
Send a test message to a mailbox at a different provider through each sending path separately: the mail platform, the marketing tool, the transactional service, the outreach tool, anything with your domain in the From header. Then read the authentication results in the raw source of what arrives.
Each path is signed independently, and each one can break independently. A domain can have five sending paths where four are perfect and the fifth has been failing since a gateway policy changed eight months ago.
Explore this expertise: Email Deliverability