DKIM canonicalization: simple vs relaxed, and why signatures break
Canonicalization normalizes a message before signing so harmless transit changes do not break DKIM. How simple and relaxed differ, and what still breaks signatures.
Mail servers modify messages in small, legal ways as they handle them: headers get re-folded across lines, whitespace gets adjusted, trailing blank lines appear. A cryptographic hash treats every one of those bytes as significant, so without countermeasures, DKIM would break on nearly every hop. Canonicalization is the countermeasure: an agreed normalization applied to headers and body before hashing, on both the signing and verifying side, so that cosmetic changes cancel out and only real modifications break the signature.
Simple vs relaxed
Simple canonicalization barely normalizes: headers must survive byte for byte, and the body tolerates only trailing empty lines. Any re-folding of a long Subject line, any whitespace adjustment by an intermediate server, and verification fails on a message nobody meaningfully changed. Relaxed canonicalization normalizes the things servers legitimately touch: header names lowercase, folded headers unfolded, runs of whitespace collapsed, trailing spaces stripped. Real modifications, changed words, added footers, altered links, still break the hash in either mode.
What survives which mode
| Feature | simple | relaxed |
|---|---|---|
| Header re-folded across lines | breaks | survives |
| Whitespace collapsed in a header | breaks | survives |
| Header name case changed | breaks | survives |
| Trailing blank lines added to body | survives | survives |
| Footer appended to body | breaks | breaks |
| Content or links modified | breaks | breaks |
The c= tag declares the mode as header/body, defaulting to simple/simple when absent, which is a default nobody should accept. relaxed/relaxed is the production standard, and every mainstream signer (OpenDKIM, Rspamd, ESP platforms) either defaults to it or should be configured to it. There is no meaningful security cost: relaxed does not tolerate content changes, only formatting ones.
What still breaks signatures in transit
With relaxed/relaxed in place, surviving breakage has real causes. Mailing lists that add subject prefixes ([listname]) or body footers modify signed content, which is why list mail fails DKIM and why lists rewrite the From header to their own domain. Corporate gateways that append disclaimers or rewrite links for scanning (common in security products) break the body hash for every message they touch. Encoding transformations, an intermediate server re-encoding quoted-printable or altering line endings in ways canonicalization does not cover, break signatures rarely but confusingly.
None of these are fixable from the sender's side; they are properties of the path the mail takes. The mitigations are architectural: DMARC needs only one aligned pass, so aligned SPF can carry messages whose DKIM broke at a gateway (when the path preserves the envelope), ARC can preserve original verdicts through cooperating intermediaries, and the residual failure rate from modifying forwarders is the accepted cost of enforcement discussed in the DMARC limitations entry.
Diagnosing a broken signature
From symptom to cause
- 1
Read the failure detail
Authentication-Results distinguishes body hash mismatch (content changed after signing) from signature verification failure (headers changed, or wrong key) from key lookup problems.
- 2
Check the c= tag
simple in either position on a stream with intermittent failures is the likely cause; move to relaxed/relaxed.
- 3
Trace the path
Received headers show the intermediaries. A gateway, list, or forwarding hop between signer and receiver is the modification suspect for body hash mismatches.
- 4
Compare sent and received copies
Diffing the delivered message against the sent original shows exactly what changed: a footer, a rewritten link, a re-encoded body. The diff names the culprit.
Frequently asked questions
Is relaxed canonicalization less secure than simple?
Can header and body modes differ?
Why does my mail fail DKIM only for some recipients?
Does canonicalization protect against replay attacks?
Key takeaways
- Canonicalization normalizes messages before hashing so legal transit changes do not break signatures
- Use relaxed/relaxed; the simple default breaks intermittently on ordinary server behaviour with no security benefit
- Content changes still break the hash in every mode: footers, link rewriting, and list prefixes are the real-world signature killers
- Path modifications cannot be fixed from the sender side; aligned SPF, ARC, and accepted residual failure are the mitigations
- Diagnose with the failure detail in Authentication-Results plus a diff of sent versus received copies