Email · MIME · 7 min read

Base64 in email: how MIME attachments work.

Every email with an attachment hides Base64-encoded binary inside it. Here's how MIME wraps that Base64, what the 76-character line rule is about, and how to extract attachments by hand.

Why email needs encoding at all

SMTP — the protocol email travels on — was specified in 1982, before binary attachments were a thing. The original spec assumes 7-bit ASCII only: no bytes above 0x7F, no long lines, no control characters except newline and tab. A modern email with a PDF attachment violates all three constraints.

MIME (Multipurpose Internet Mail Extensions, RFC 2045) is the framework that lets binary attachments survive SMTP. The trick: encode the binary in a way that does fit 7-bit ASCII. Base64 is the encoding it uses.

What a MIME email looks like

If you "view source" on an email with an attachment, you'll see something like this:

From: alice@example.com
To: bob@example.com
Subject: Report
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_42"

------=_Part_42
Content-Type: text/plain; charset="utf-8"

Here's the quarterly report.

------=_Part_42
Content-Type: application/pdf; name="report.pdf"
Content-Disposition: attachment; filename="report.pdf"
Content-Transfer-Encoding: base64

JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlIC9DYXRhbG9nCi9QYWdl
cyAyIDAgUgo+PgplbmRvYmoKMiAwIG9iago8PC9UeXBlIC9QYWdlcwo...

------=_Part_42--

The Content-Transfer-Encoding: base64 line tells the receiving mail client that everything below is Base64. The decoder turns it back into the original PDF.

The 76-character line rule

MIME Base64 (RFC 2045 §6.8) requires that lines be no longer than 76 characters. This is a holdover from the SMTP spec, which limits lines to 998 octets and recommends 78.

If you decode a MIME-style Base64 string and it has internal newlines, every Base64 decoder should ignore them. Our decoder strips whitespace before decoding, so wrapped Base64 from email source works directly.

Base64 vs Quoted-Printable

MIME supports two transfer encodings: Base64 and Quoted-Printable. They're optimized for different data:

Base64Quoted-Printable
Best forBinary attachmentsMostly-ASCII text with occasional non-ASCII
Size overhead+33%+1–10% for mostly-ASCII, up to +200% for binary
Human-readableNoMostly yes
ExampleY2Fmw6kg4piVcaf=C3=A9 =E2=98=95

A French email body might use Quoted-Printable; a JPEG attachment will always use Base64.

Encoding email headers: a separate scheme

Non-ASCII characters in headers (a subject like =?utf-8?B?Q29uZ3JhdHVsYXRpb25z?=) use a related but distinct format defined in RFC 2047. The ?B? marks the Base64 variant, and the encoded portion is between ? markers. To decode such a subject, extract the Base64 between the markers and paste it into the decoder.

Extracting attachments from a raw email

If you have a .eml file and want to pull out an attachment by hand:

  1. Open the file in a text editor.
  2. Find the part marked Content-Transfer-Encoding: base64.
  3. Copy the Base64 block (between the blank line and the next --boundary).
  4. Decode it with the decoder.
  5. Save the result with the original filename and extension from the Content-Disposition line.

For one-off attachments this is fine. For doing it at scale, use a proper MIME parser (Python's email module, JavaScript's mailparser, etc.).

Why some emails arrive corrupted

The classic Base64-in-email problem: the email passed through a gateway that "helpfully" reformatted the Base64 — converting tabs to spaces, normalizing line endings, or wrapping long lines differently. Most of the time the corruption is invisible, because the Base64 alphabet contains no whitespace-sensitive characters. But if the gateway dropped a character entirely, the rest of the decoded output will be garbage from that point on.

If a Base64 attachment fails to open and the same file works when sent through a different mail path, gateway corruption is the likely cause.


Published May 2026 · Last reviewed May 2026. Spot an error? Email contactus@base64decode.tools.

Run it yourself

Try the decoder.