On this page
MIME File Attachments & Binary Data Transport
Attach documents and assets using RFC 2183 Content-Disposition, RFC 2231 international filename encoding, Base64 transfer encoding, and 10MB size ceilings.
What it is
File attachment handling in email is governed by MIME standards (RFC 2045, RFC 2046, and RFC 2183), which define how arbitrary binary data - such as PDF invoices, CSV spreadsheets, and document archives - is encoded into 7-bit ASCII text and presented to email client interfaces.
An attached file is serialized as an independent MIME body part within a multipart/mixed container:
Content-Type: multipart/mixed; boundary="boundary-mixed-98234"
--boundary-mixed-98234
Content-Type: multipart/alternative; boundary="boundary-alt-123"
[...Plain text and HTML message body parts...]
--boundary-mixed-98234
Content-Type: application/pdf; name="invoice_2026_088.pdf"
Content-Disposition: attachment; filename="invoice_2026_088.pdf"; size=1048576; modification-date="Tue, 25 Aug 2026 14:30:00 +0000"
Content-Transfer-Encoding: base64
JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIK
Pj4KZW5kb2JqCjIgMCBvYmoKPD...[Base64 binary payload]...==
--boundary-mixed-98234--
Why it matters
- 33% Base64 Wire Size Inflation: Binary files encoded into Base64 expand by approximately 33% in byte size on the wire. A 15 MB PDF file results in a ~20 MB email message, which exceeds the message size limit on many corporate email gateways.
- International Filename Truncation (RFC 2231): Standard ASCII headers cannot represent non-Latin characters (such as Japanese, Chinese, Arabic, or accented European letters). Using raw UTF-8 in
filename="..."causes filenames to become corrupted (e.g.,invoice_???.pdf) on older mail clients. - Security Quarantine on Executables: Attaching files with ambiguous MIME types or prohibited extensions triggers immediate virus quarantine by recipient mail servers.
How to implement
1. Set the correct Content-Disposition header parameters:
Explicitly declare attachment (to instruct the mail client to offer a download prompt) and specify the filename parameter:
Content-Disposition: attachment; filename="monthly_report.pdf"
2. Encode International Filenames using RFC 2231:
For filenames containing non-ASCII characters or spaces, use RFC 2231 parameter encoding (filename*):
Content-Disposition: attachment; filename*="UTF-8''re%C3%A7u_financier_ao%C3%BBt_2026.pdf"
Modern mail generation libraries (Nodemailer, Python email, Go net/mail) handle RFC 2231 encoding automatically when provided with Unicode strings.
3. Enforce Strict Attachment Size Ceilings:
- Recommended Maximum Attachment Size: 10 MB (results in ~13.3 MB over the wire).
- Absolute Hard Ceiling: 25 MB (maximum limit supported by Google Workspace and Microsoft 365).
- For files larger than 10 MB, upload the file to a secure cloud storage bucket and embed a time-limited, signed download link in the HTML email body instead of attaching the raw binary.
4. Run Antivirus & Malware Scanning Before Dispatch: All user-uploaded attachments must be scanned with an automated antivirus engine (e.g., ClamAV, AWS GuardDuty) before being attached to outbound transactional emails.
Common mistakes
- Forgetting Base64 Padding and Line Wrapping: Base64 data lines must be wrapped with
\r\nevery 76 characters per RFC 2045 §6.8. Emitting a single un-wrapped million-character line breaks line length limits on MTAs. - Mislabelling
Content-Disposition: inlineasattachment: Tagging inline logos asattachment, causing the email client to display the company logo twice (once in the header, and once as a downloadable file at the bottom). - Using Generic
application/octet-streamfor Standard Files: Always declare the exact MIME media type (e.g.,application/pdf,text/csv,image/png) so mobile clients can open files in the appropriate native app viewer. - Allowing Path Traversal in Filenames: Failing to sanitize user-provided filenames, allowing strings like
../../etc/passwd.pdfintoContent-Disposition.
Verification
1. Inspect Base64 payload and MIME headers with standard utilities:
# Verify attachment content-type and filename
python3 -c "
import email
msg = email.message_from_bytes(open('invoice_msg.eml', 'rb').read())
for part in msg.walk():
if part.get_content_disposition() == 'attachment':
print('Attachment:', part.get_filename(), 'Type:', part.get_content_type())
"
2. Test delivery to size-constrained endpoints:
Send maximum-size test attachments to Gmail and Outlook accounts to confirm that message delivery completes without 552 5.3.4 Message size exceeds fixed maximum message size errors.