MIME Email Attachments and Base64 Encoding
In SMTP, a Base64 attachment is a MIME part, not just encoded text.
SMTP was designed for 7-bit ASCII text in 1982.1 Binary attachments, PDFs, images, spreadsheets, require Base64 encoding to survive transmission through SMTP relays that strip or corrupt bytes with values above 127.
MIME (Multipurpose Internet Mail Extensions) defines the multipart message format that wraps attachments alongside the email body.2 Each attachment part specifies Content-Type, Content-Transfer-Encoding: base64, and the Base64-encoded content, which MIME decoders in email clients then decode.
How MIME Base64 encoding works
A MIME-encoded attachment occupies its own section in the email. The section opens with a Content-Type header (such as application/pdf; name="report.pdf"), followed by Content-Transfer-Encoding: base64, a blank line, then the Base64-encoded content wrapped at 76 characters per line with CRLF line endings (not LF). The 76-character line limit is mandatory per RFC 2045 , some older SMTP servers reject longer lines. Consequently, MIME Base64 output is longer than raw Base64 by approximately 2.6% (one CRLF pair per 76 characters).2 Building on this, Content-Disposition: attachment; filename="report.pdf" tells the email client to offer the attachment as a download rather than displaying it inline.
Keeping MIME line wrapping predictable
Use a MIME-aware encoder rather than a raw Base64 string when generating full message parts. The line breaks are part of the format, not cosmetic formatting, and they help older mail servers parse the attachment reliably. Python's email.mime.base.MIMEBase and Java's MimeBodyPart both handle the CRLF wrapping and line-length enforcement automatically, which means you should never manually construct MIME parts with raw Base64 unless you are prepared to replicate the RFC 2045 formatting rules exactly.
This matters because the failure mode is silent: a hand-rolled part that breaks the 76-character rule or uses LF instead of CRLF often validates locally and then fails only on a strict relay, so the bug surfaces in production rather than in your test mailbox. Building the part by hand also means you personally own every formatting decision, so a single copy-paste error from an old example can ship to real recipients before anyone notices.
Common pitfalls and variants
Line endings matter because MIME requires CRLF (\r\n) between each 76-character line, while Unix tools write LF only and Windows tools write CRLF by default, creating a cross-platform compatibility issue that silently corrupts attachments when the line endings do not match the standard. A attachment encoded on a Unix system with LF line endings may pass validation locally but fail when relayed through an SMTP server that enforces the MIME CRLF requirement, producing a broken attachment on the recipient's side with no error reported to the sender.
Keeping line endings and charset headers aligned
Sending LF-only MIME through a strict SMTP relay causes encoding errors that corrupt the attachment content when the relay rejects or modifies the message due to non-standard line endings. Furthermore, the character set of text attachments must be declared in the Content-Type header, such as Content-Type: text/plain; charset=UTF-8. Omitting the charset causes email clients to guess, often producing garbled non-ASCII text. The Content-Transfer-Encoding: base64 header applies to binary parts only; text parts typically use quoted-printable encoding, which is more human-readable and preserves line structure in plain text emails. A practical way to verify your MIME output is to pipe it through formail or a MIME parser before sending, which reports line-ending errors and missing headers that are difficult to spot by eye in raw message source.
Security and best practice
Inline images in HTML email use Content-ID (CID) references: Content-ID: <[email protected]>. The HTML body references them with src="cid:[email protected]". This causes email clients to render the image without an external HTTP request. Alternatively, data URIs in the HTML body embed Base64-encoded images directly, which works in Gmail, Apple Mail, and iOS Mail. MIME-encoded attachments have no size limit at the encoding level, but most mail servers enforce a per-message limit between 10 MB and 100 MB. A 10 MB PDF attachment encodes to roughly 13.3 MB of Base64 , well within common limits. The CID approach is generally preferred over data URIs for inline images because it keeps the HTML body smaller and compatible with a wider range of email clients, including Outlook for Windows which has limited data URI support.
Testing MIME structures before deployment
Before deploying an email campaign or transactional template, validate the MIME structure with a raw message viewer. Most mail clients show rendered HTML; to inspect the actual MIME parts, download the .eml file (available in Gmail via 'Show original' and in Outlook via 'View message source') and open it in a plain text editor or MIME parser. Verify that each attachment part carries Content-Transfer-Encoding: base64, that no line exceeds 76 characters, and that the boundary strings separating each MIME part are unique and consistent throughout the message.
Sending test messages to SMTP validators
SMTP validation services accept an SMTP connection to a dedicated test address and report MIME errors, spam-score issues, and malformed attachment headers. Sending your outgoing template to one of these services before deployment catches CRLF errors, incorrect charset declarations, and oversized Base64 blocks that strict relay servers reject. Validate both the plain-text and HTML parts of a multipart message, since encoding errors in either part can prevent the entire message from delivering correctly.
Size planning for attachments and server limits
Server-side email attachment size limits vary across providers. Gmail accepts messages up to 25 MB total, including all headers and encoding overhead.3 Microsoft 365 Exchange Online defaults to 35 MB per message.4 Base64 expands each attachment by 33%, so a 7.5 MB PDF occupies 10 MB after encoding.5 The combined encoded size of all attachments in a multipart message contributes to this total, not each attachment individually.
For large attachments, a link-to-download approach avoids the size constraint entirely: upload the file to cloud storage, generate a time-limited download link, and include the link in the message body instead of attaching the file. This also bypasses the security filters that some mail gateways apply to executable or archive attachments by inspecting byte signatures in the Base64-encoded content. Recipients at organizations with attachment scanning also receive the message faster when large binary content travels out-of-band.
When to use this
Use MIME Base64 encoding for email attachments, inline CID images, and any binary content in email messages. Use Content-Transfer-Encoding: quoted-printable for text parts that need to preserve line structure and remain partially human-readable. If a .eml export looks wrong, reconstruct the attachment from its Base64 block to confirm it matches the original file before you blame the mail server.
Examples
MIME attachment part structure
Content-Type: application/octet-stream <raw binary>
Content-Type: application/pdf; name="report.pdf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="report.pdf" JVBERi0xLjQKJcfs...
Each MIME part must end with CRLF before the boundary separator.
Encode an attachment in Python (smtplib)
from email.mime.text import MIMEText
msg = MIMEText('Hello') from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
msg = MIMEMultipart()
with open('report.pdf', 'rb') as f:
part = MIMEBase('application', 'pdf')
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename='report.pdf')
msg.attach(part) encoders.encode_base64() handles line-wrapping and CRLF automatically.
- 1.
J. Postel, "Simple Mail Transfer Protocol," RFC 821, IETF, August 1982. https://datatracker.ietf.org/doc/html/rfc821
- 2.
N. Freed and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies," RFC 2045, IETF, November 1996. https://www.rfc-editor.org/rfc/rfc2045.html
- 3.
"Send attachments with your Gmail message," support.google.com, accessed June 2026. https://support.google.com/mail/answer/6584
- 4.
"Exchange Online limits," learn.microsoft.com, accessed June 2026. https://learn.microsoft.com/en-us/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits
- 5.
"Base64," Wikipedia, accessed June 2026. https://en.wikipedia.org/wiki/Base64