Open a raw email body in "view source" mode and odds are it was packaged by one of two workhorse schemes: base64 or quoted-printable. Pick the wrong one, or let a relay mangle it in transit, and you get mojibake, broken attachments, or a DKIM signature that fails for no reason anyone can immediately explain. Here's a side-by-side technical comparison of how each encoding works, when to choose which, and what happens when the choice goes wrong.

Email Decoded's MIME chapter treats Content-Transfer-Encoding as one of the most misdiagnosed fields in a header block. The symptom, garbled text, rarely points directly at the cause. That cause is usually a wrong encoding choice, or a lossy re-encoding somewhere in transit. This article is the practical companion to that chapter, with annotated specimens instead of RFC prose.

What Content-Transfer-Encoding Actually Solves

SMTP was born in the early 1980s to move plain 7-bit ASCII text between machines. Nothing else. No accented characters, no attachments, no images, no binary files of any kind. That constraint didn't go away when email started carrying photos, PDFs, and text in Japanese, Arabic, or Cyrillic.

MIME solved this by adding a header field: Content-Transfer-Encoding. Nathaniel Borenstein and Ned Freed published the first version as RFC 1341 in June 1992. The set in force today is RFC 2045 and its companions, from November 1996. The field tells the receiving client how the body was packaged for transport, so the client can unpack it correctly on arrival. Without it, a mail client has no reliable way to know whether a string of bytes is raw UTF-8 text, base64-wrapped binary, or something else entirely.

If you want the full picture of how MIME structures a message before it ever gets to encoding choices, MIME encoding from first principles covers the header-and-body architecture this article builds on.

Why 7bit and 8bit email encoding broke non-ASCII content

The 7bit encoding label means every byte in the body uses only the lower 128 ASCII values, with lines capped at 998 characters. That's fine for English text with no special characters. It can't represent an é, a €, or a Chinese character at all.

8bit was the next attempt: allow full byte values, but keep the same line-length rules. Many mail servers of the era, and quite a few relays still running today, don't reliably pass 8-bit clean data. Some strip the high bit. Some choke on binary-looking bytes and reject or corrupt the message. Relying on 8bit transport for a modern UTF-8 body is a bet you can still lose. That's exactly why quoted-printable and base64 exist: both guarantee 7-bit-safe transport regardless of what the underlying network actually supports.

Quoted-Printable Encoding Mechanics

Quoted-printable is built for content that's mostly plain ASCII text with the occasional non-ASCII character mixed in. It leaves ordinary letters, digits, and most punctuation untouched. Anything outside the safe 7-bit printable range gets escaped as an equals sign followed by two hex digits: the byte's value in hexadecimal. The equals sign itself is the escape character, so a literal = in the source always becomes =3D.

So the em-dash character, encoded in UTF-8, might show up in a raw body as =E2=80=94. A reading client that understands quoted-printable decodes that sequence back into the original character. A client that doesn't just shows you the raw escape codes.

Soft Line Breaks and the 76-Character Limit

Quoted-printable enforces a maximum line length of 76 characters. When an encoded line would run longer, the encoder inserts a soft line break: a trailing equals sign followed by a hard CRLF. The receiving client is supposed to strip that equals-sign-plus-newline pair back out during decoding, rejoining the line as if the break never happened.

This is different from a real paragraph break, which appears in the source as an actual line ending with no trailing equals sign. The encoding has to preserve that distinction. Otherwise paragraphs collapse into a single mangled line, or a soft break gets treated as intentional and adds unwanted blank lines.

When Quoted-Printable Distorts Plain Text

Because quoted-printable is nearly identical to plain ASCII for English-language content, a raw quoted-printable body usually still reads recognizably. That's part of its appeal: even without decoding, a human glancing at the source can follow most of the text.

The distortion shows up around the edges. Trailing whitespace at the end of a line gets encoded rather than left bare, because bare trailing spaces and tabs are unreliable across transport, and some systems strip them. A raw message body showing =E2=80=99 where a curly apostrophe should be is a textbook quoted-printable artifact, not file corruption. The hex escape simply wasn't decoded by the reading client. The same thing happens with accented letters, curly quotes, em dashes, and any character outside the base ASCII set. If the display shows literal =XX sequences, blame the renderer for not decoding quoted-printable, not the original message.

Base64 Encoding Mechanics

Base64 takes a completely different approach: it doesn't try to preserve readability at all. It converts the entire body into a stream of 64 safe printable characters, the letters A–Z and a–z, digits 0–9, plus + and /, regardless of what the original data looked like. A 65th character, =, appears only as padding at the very end of the stream, when the input didn't divide evenly into groups.

The mechanism works in fixed 3-byte groups. Every 3 raw bytes of input become 4 base64 characters of output. That mapping is purely mathematical, so base64 doesn't care whether the source data is French text, a JPEG image, or a compiled binary. It treats all input the same way, byte for byte.

Fixed 76-Character Wrapping and Binary Safety

Like quoted-printable, base64 output is wrapped at a fixed line length of 76 characters per RFC 2045, purely to satisfy SMTP's line-length limits. But unlike quoted-printable, those wraps carry no semantic meaning. They're not soft line breaks tied to the source content. They're just periodic newlines dropped into an otherwise continuous stream of characters, and a decoder simply strips all the newlines and processes the result as one block.

That property is what makes base64 completely binary-safe. There's no escape mechanism to negotiate, no ambiguity about whitespace, and no risk of a byte value colliding with a control character. It's why attachments, images, and any content with a non-Latin script, Japanese, Korean, Cyrillic, Arabic, overwhelmingly ship as base64 rather than quoted-printable.

Why Base64 Email Body Encoding Bloats Message Size

Base64 encoding expands binary data by roughly one-third, because it maps every 3 raw bytes into 4 printable characters. A 3 MB attachment becomes roughly 4 MB on the wire. For a short plain-text email that overhead is trivial. For large attachments, it's a meaningful chunk of bandwidth and storage. That's exactly why mail gateways enforce message-size limits measured against the encoded size, not the original file size.

That overhead is the price of guaranteed transport safety. For binary content, there's no cheaper 7-bit-safe alternative that works as reliably, so the tradeoff gets accepted as a cost of doing business.

Base64 vs Quoted-Printable: Side-by-Side Comparison

Comparing base64 vs quoted-printable email encoding comes down to three practical axes: size overhead, human readability in raw view, and resilience to mangling by relays along the delivery path.

On overhead, quoted-printable wins for text that's mostly ASCII, because untouched characters cost nothing extra and only the exceptions get escaped. Base64 always costs the same roughly 33% expansion, whether the source is English prose or a densely non-ASCII script, because it encodes every byte uniformly.

On readability, quoted-printable is the clear winner for plain-text troubleshooting. A support engineer can open a raw quoted-printable body and read most of it directly. A base64 body is an opaque character block. You can't glance at it and know what it says; you have to decode it first.

Readability, Overhead, and Corruption Risk

On resilience, the picture flips. Quoted-printable's structure lives in exactly the characters a relay is tempted to touch: the = escapes, the soft line breaks, and the CRLF line endings. A relay that normalizes line endings or reflows long lines can corrupt a quoted-printable body without touching a single "real" character. Base64's opaque character stream is more resistant to this class of damage, because there's no meaningful whitespace or line-ending semantics for a relay to accidentally disturb, as long as the relay doesn't touch the base64 characters themselves.

In short: quoted-printable is cheap and readable but structurally sensitive to whitespace and line handling. Base64 is heavier but structurally indifferent to formatting. That's exactly why it's the safer default for binary and non-Latin content.

How Transfer Encoding Interacts With DKIM Body Canonicalization

DKIM doesn't sign a message's raw bytes as they left the sender's server. It signs a canonicalized version of the body, a normalized form defined by RFC 6376. There are two body canonicalization modes, and the signer declares its choice in the signature's c= tag. Simple mode removes only empty lines at the end of the body; everything else must survive transit byte for byte. Relaxed mode also strips whitespace at the ends of lines and collapses runs of spaces and tabs inside them. The default is simple, but production signers overwhelmingly publish relaxed, precisely because gateways routinely shuffle whitespace without changing meaning. The signature is computed as a hash over the canonicalized body, then verified the same way at the receiving end.

That's the theory. In practice, the encoding of the body matters enormously, because canonicalization normalizes some things and not others. It doesn't decode or re-encode Content-Transfer-Encoding at all. It operates on the encoded body exactly as transmitted. So if a relay between the signer and the recipient decodes a base64 or quoted-printable body, modifies it (even trivially, like adding a disclaimer), and re-encodes it, the resulting bytes almost never match the original hash the signer computed. The signature fails, even though nothing "malicious" happened.

Why Re-Encoding Breaks Signatures

This is why encoding stability matters so much for signature validity. An email that was signed cleanly at the source but arrives with a broken signature after transiting a legacy relay that normalizes line endings or re-wraps base64 lines is a classic body-canonicalization mismatch, not a spoofing attempt. The relay didn't forge anything; it just touched bytes that were part of the signed hash input.

Quoted-printable bodies are fragile here in one specific way. Their soft line breaks are made of = and CRLF, and a relay that normalizes bare line feeds or reflows lines rewrites exactly those bytes. Whether the signature survives depends on the canonicalization mode: relaxed forgives whitespace-level changes, simple forgives almost nothing. Base64's opaque stream resists well-meaning cleanup better, but it isn't immune if a relay decides to re-wrap the line length under simple canonicalization.

If a signature is failing and you suspect this is the cause, why DKIM signature verification fails walks through the canonicalization modes and how to isolate a re-encoding relay as the culprit. Pair that with reading the Authentication-Results header to see exactly where in the chain the hash comparison diverged.

Choosing and Troubleshooting the Right Encoding

The practical rule is simple once you separate content types. Quoted-printable is the right choice for text bodies that are overwhelmingly ASCII with only occasional non-Latin characters. Most English, French, German, or Spanish email content fits this profile well, since it stays readable in raw form and keeps overhead low.

Base64 is the right choice for attachments, images, any binary content, and text bodies written primarily in non-Latin scripts. Quoted-printable's per-byte escaping would balloon size there, and readability wouldn't be preserved anyway. UTF-8 email encoding for a body written in, say, Japanese or Arabic gains nothing from quoted-printable's ASCII-friendliness, since almost every character would need escaping. Each escaped byte costs three characters, and a single Japanese character is three bytes in UTF-8 — nine encoded characters for one visible glyph. Base64's flat 33% overhead ends up far smaller in practice for that kind of content.

Compatibility Across Mail Clients and Gateways

Most modern clients handle both encodings correctly, but email encoding compatibility issues still surface at the margins: older webmail systems, some corporate gateways with legacy content filtering, and automated parsers that assume a specific encoding rather than reading the header. When you're building or debugging a mail pipeline, always trust the Content-Transfer-Encoding header rather than guessing from the body's appearance.

Diagnosing Encoding Corruption in Raw Headers

When you see mojibake, strings like é where an é should be, or literal =XX hex codes leaking into rendered text, the fastest diagnosis is to check three things in order. First, look at the Content-Transfer-Encoding header and confirm which scheme the sender declared. Second, check the Content-Type header's charset parameter; a mismatch between the declared charset and the actual byte encoding produces exactly this kind of garbling. Third, check whether any relay in the path could plausibly have decoded and re-encoded the body. That's the most common way a correctly-encoded message gets corrupted after leaving the sender.

For a more general walkthrough of how to isolate these problems in a header block, how to read email headers to diagnose failures covers the sequence of fields to check before you conclude the message itself is broken. And because encoding issues often show up alongside authentication failures, how SPF, DKIM, and DMARC actually work together is worth reading if a garbled body and a failed signature are showing up on the same messages.

Encoding problems rarely travel alone. They tend to show up next to deliverability symptoms that look unrelated at first glance. If you're chasing down a pattern across many messages rather than one specimen, deliverability troubleshooting by symptom class organizes those symptoms so you can match what you're seeing to a likely root cause faster than trial and error.

Base64 and quoted-printable aren't competing standards fighting for dominance. They're two tools solving the same 7-bit-transport constraint for different kinds of content. Once you can read a raw header and recognize which one you're looking at, and why, most "corrupted email" tickets stop being mysteries. The Email Decoded MIME Encoding chapter goes deeper into the header-level mechanics behind this comparison, and the full book builds that same specimen-driven approach across the rest of the delivery chain.