DKIM Canonicalization: Simple vs Relaxed, Explained Properly
Why a signature computed over exact message bytes would break constantly in transit, and how DKIM's two canonicalization algorithms solve that in genuinely different ways.
The Problem Canonicalization Exists to Solve
A message doesn't travel from sender to recipient over a single, unbroken wire. It typically passes through several intermediate systems — the sender's outbound relay, possibly a forwarding service, spam filtering infrastructure, the recipient's inbound gateway — and each of these has historically made small, usually harmless adjustments to a message in transit: converting line endings between different conventions, folding long header lines differently, trimming trailing whitespace, or adjusting header capitalization. None of these changes alter what a message actually says or means. But a cryptographic signature computed over exact raw bytes is, by design, sensitive to every single byte — change one character anywhere in the signed content, and the signature no longer verifies, regardless of whether that change was malicious tampering or an entirely innocuous whitespace adjustment made by a relay server along the way.
Canonicalization is DKIM's answer to this tension. Rather than signing the message's literal raw bytes, DKIM signs a canonicalized (normalized) form of it, computed by applying a defined, standardized transformation first. Both the signer and every verifier apply the identical transformation, so as long as a message's meaningful content survives transit unchanged, the canonicalized form both sides compute stays identical too, even if the raw bytes differ slightly due to routine in-transit handling.
Simple vs. Relaxed, Rule by Rule
| Aspect | Simple | Relaxed |
|---|---|---|
| Header name case | Must match exactly | Lowercased before hashing |
| Header whitespace | Must match exactly | Multiple spaces/tabs collapsed to one |
| Header folding/unfolding | Preserved exactly | Unfolded and normalized |
| Body trailing empty lines | Removed (only tolerance allowed) | Removed |
| Body internal whitespace | Must match exactly | Collapsed to single spaces |
| Body line endings | Must match exactly | Normalized |
| Overall tolerance | Very low | Substantially higher |
Working Through a Concrete Example
Consider a Subject header written as Subject: Your Invoice (with extra spaces after the colon due to how some mail software formats headers). Under simple header canonicalization, that extra whitespace is part of the exact byte sequence being hashed, so a relay that trims it down to Subject: Your Invoice would break the signature entirely, even though nothing about the actual subject line's meaning changed. Under relaxed header canonicalization, that whitespace gets collapsed to a single space as part of the normalization process before hashing ever happens, so both the original and the trimmed version normalize to the identical canonical form, and the signature survives that specific kind of modification without issue.
The same logic applies to the body. A forwarding service that converts line endings from one convention to another, entirely routine and content-preserving, would break a simple-canonicalized body hash but leave a relaxed-canonicalized one intact, since relaxed body canonicalization normalizes line endings as part of its transformation.
Why Relaxed Became the De Facto Standard
When Simple Canonicalization Is Still Chosen
Despite relaxed's dominance, simple canonicalization isn't obsolete or wrong to use — it's a deliberate, valid choice for situations where the strongest possible tolerance-free integrity guarantee matters more than resilience to in-transit handling. Some high-assurance or regulated environments specifically prefer simple canonicalization's stricter exact-match behavior precisely because it fails loudly on any modification at all, treating that as a feature rather than a limitation when the priority is detecting even benign changes rather than maximizing deliverability through lenient tolerance.
Canonicalization and the Body Hash Together
It's worth understanding that canonicalization mode directly determines what the body hash (the bh= tag, covered in depth in a companion guide) actually contains. The body isn't hashed in its raw form under either mode — it's canonicalized first, according to whichever body algorithm the c= tag specifies, and the hash is computed over that canonicalized result. This means the identical message body produces two different bh= values depending on which canonicalization mode is in use, which is exactly why a verifier must know the canonicalization mode (read directly from the c= tag) before it can correctly recompute and check the body hash.
A Byte-Level Trace of Relaxed Header Canonicalization
To make the transformation completely concrete, walk through exactly what relaxed header canonicalization does to a single header line, step by step. Starting with a raw header as it might arrive over the wire: From: Example Sender <sender@example.com>, note the header name's mixed case isn't actually shown here since From is already capitalized correctly, so consider instead a header arriving as FROM: Example Sender <sender@example.com>. Relaxed canonicalization first lowercases the header name, producing from:. It then collapses the runs of multiple spaces after the colon and between words down to single spaces, and trims any trailing whitespace at the end of the line, yielding from:Example Sender <sender@example.com>. This exact normalized string, not the original raw bytes, is what actually gets included in the hash computation. A verifier receiving the header in any equivalently-formatted variation — different capitalization, different spacing — performs the identical normalization and arrives at the identical canonical string, so the hash still matches.
Why Some Headers Are More Sensitive to Canonicalization Choice Than Others
Not every header is equally likely to be modified in transit, which means the practical difference between simple and relaxed canonicalization matters more for some headers than others. Headers like Date and Message-ID are typically set once by the originating system and rarely touched afterward, so canonicalization mode makes little practical difference for them in most cases. Headers like Subject, on the other hand, are frequently modified by intermediate systems — mailing lists commonly prepend a list name in brackets, some corporate gateways add a classification tag, spam filters occasionally annotate suspicious subjects — making Subject one of the headers where relaxed canonicalization's added tolerance provides the most practical, observable benefit in terms of signature survival through real-world mail handling infrastructure.
Canonicalization's Relationship to the h= Tag
It's worth being precise about a distinction that's easy to blur: the h= tag in a DKIM signature lists which specific headers are included in what gets signed at all, while canonicalization mode governs how those already-selected headers get normalized before hashing. These are independent decisions. A signature could specify h=from:to:subject:date, meaning only those four headers are covered by the signature regardless of what else the message contains, and separately specify c=relaxed/relaxed, meaning those four selected headers each get relaxed normalization applied before being included in the hash computation. Confusing these two mechanisms — assuming canonicalization mode determines which headers are protected, rather than how the protected ones are formatted — is a common source of misunderstanding when first learning how DKIM signatures are actually constructed.
Testing Canonicalization Behavior Directly
For anyone wanting to see the practical difference firsthand rather than just reading about it, a useful exercise is taking a real signed message, manually introducing a small, deliberately harmless whitespace change to a header or the body, and checking whether the signature still verifies under each canonicalization mode. Under simple mode, even a single added space typically breaks verification immediately. Under relaxed mode, that same whitespace change usually verifies fine, while a change to the actual meaningful content (altering a word, adding a sentence) still correctly breaks verification under either mode. This hands-on comparison tends to make the abstract distinction between "formatting tolerance" and "content integrity" click in a way that reading the specification's rules alone doesn't always achieve.
How Canonicalization Interacts With Multipart MIME Bodies
Real-world email bodies, especially anything with attachments or both HTML and plain-text versions, aren't simple flat text — they're structured as MIME multipart content, with boundary markers separating different parts and their own internal headers describing content type and encoding. Canonicalization, whether simple or relaxed, treats the entire body — boundary markers, part headers, and all — as one continuous stream of text to be normalized and hashed, rather than having any special awareness of MIME structure itself. This matters practically because a mail system that alters MIME boundary formatting, re-encodes an attachment, or adjusts part header whitespace during transit is making exactly the kind of body-level change that canonicalization mode determines the tolerance for, same as it would for a simple plain-text body. Attachments in particular tend to be more fragile under simple canonicalization than plain text, since encoding-related whitespace or line-length adjustments are a common, usually harmless side effect of some mail systems' attachment handling.
A Table of Canonicalization Choices Observed Across Major Senders
| Sender Category | Typical Canonicalization Choice | Likely Reason |
|---|---|---|
| Large hosted email providers | relaxed/relaxed | Maximizes signature survival across the huge variety of relays and clients their mail passes through |
| Transactional email APIs | relaxed/relaxed | Same reasoning, plus these messages are often further modified by client-side rendering |
| High-assurance/regulated senders | simple/simple or mixed | Prioritizes strict, provable integrity over maximum deliverability tolerance |
This isn't a rule enforced by any specification — it's simply the pattern that emerges from senders making the trade-off that best fits their own priorities, and it's worth checking directly (via the c= tag on an actual signed message) rather than assuming any particular sender follows the general pattern without verifying it.
Debugging a Canonicalization-Related Failure Methodically
When a DKIM failure is suspected to be canonicalization-related specifically, rather than a key or selector problem, a useful diagnostic approach is comparing the message as received against what's known or suspected about the message as originally sent, looking specifically for whitespace, capitalization, or line-ending differences in the signed headers and body. If such differences exist and the signature specifies simple canonicalization for the affected part (header or body), that's a strong, specific explanation. If the signature already specifies relaxed canonicalization and is still failing despite only these kinds of minor differences, the problem likely lies elsewhere — a genuine content change beyond what even relaxed mode tolerates, a key mismatch, or a selector pointing at the wrong record entirely — and canonicalization mode itself can be ruled out as the cause.
Canonicalization Mode and Third-Party Signing Services
Hosted email platforms handling DKIM signing on a domain's behalf almost always choose canonicalization mode internally, without exposing it as a configurable setting to the domain owner. If you're relying entirely on such a platform, understanding canonicalization is still useful for diagnosing forwarding or mailing-list-related verification failures, even though you have no direct control over changing the mode — the diagnostic value doesn't depend on being able to act on it yourself.
Canonicalization Choice as Part of a Vendor Evaluation
For organizations evaluating a new email sending platform specifically for high-assurance or compliance-sensitive use cases, it's reasonable to ask a prospective vendor directly which canonicalization mode their DKIM signing uses, alongside the more commonly asked questions about key length and rotation practice. A vendor unable to answer this specific question, or whose documentation doesn't mention it at all, isn't necessarily disqualifying on its own, but it's a useful signal about how deeply the vendor's team understands and has deliberately configured their own authentication infrastructure versus having accepted whatever default their underlying mail-sending library happened to ship with.
Related Reading in This Series
For a deeper look specifically at how the body hash itself is computed, see DKIM Body Hash Explained. For the fundamentals of DKIM signing and verification end to end, read What Is DKIM. For how the selector referenced in a signature ties into key lookup, see DKIM Selectors. To inspect a domain's actual DKIM record, open DKIM Lookup.
ToolsNovaHub tools are built and independently maintained with a focus on accurate, no-signup network and security utilities. Spotted an error? Let us know.
📋 Related Tools & Guides Comparison
| Resource | Type | Link |
|---|---|---|
| DKIM Lookup | Tool | Open Tool → |
| DKIM Body Hash Explained | Guide | Read Guide → |
| What Is DKIM | Guide | Read Guide → |
| DKIM Selectors | Guide | Read Guide → |
| DMARC Lookup | Tool | Open Tool → |