RFC 2046: MIME Part 2 — Media Types
Why This Exists
RFC 2045 introduced Content-Type and transfer encodings, but it didn't define what content types exist or how they behave. RFC 2046 fills that gap by defining:
- The top-level media types (text, image, audio, video, application, multipart, message).
- The multipart mechanism that allows a single email to contain multiple body parts with a boundary delimiter.
- Specific multipart subtypes that control how mail clients display the parts (mixed, alternative, digest, parallel).
This is the RFC that makes modern email possible. Without it, every email would be a single block of text.
How It Works
The Top-Level Media Types
| Type | Description | Common Subtypes |
|---|---|---|
text |
Human-readable text |
text/plain, text/html, text/calendar
|
image |
Image data |
image/png, image/jpeg, image/gif, image/svg+xml
|
audio |
Audio data |
audio/mpeg, audio/ogg
|
video |
Video data |
video/mp4, video/webm
|
application |
Binary data or structured formats |
application/pdf, application/json, application/octet-stream
|
multipart |
Multiple body parts in one message |
multipart/mixed, multipart/alternative, multipart/related
|
message |
Encapsulated email message |
message/rfc822, message/delivery-status
|
The Multipart Mechanism
Multipart types are the heart of RFC 2046. A multipart message contains a boundary parameter that delimits each part:
Content-Type: multipart/mixed; boundary="----=_boundary_001" ------ preamble (ignored by MIME clients) ------ ------=_boundary_001 Content-Type: text/plain; charset=utf-8 This is the first part. ------=_boundary_001 Content-Type: text/plain; charset=utf-8 This is the second part. ------=_boundary_001-- ^^^ note the trailing -- which marks the end
Key rules for boundaries:
- Each part is preceded by
--+ the boundary string on its own line. - The final boundary has
--appended after it as well (e.g.,--boundary--). - The boundary string must not appear in any body part. Use a long, random string.
- Content before the first boundary (the preamble) and after the final boundary (the epilogue) are ignored by MIME-aware clients.
Multipart Subtypes
The subtype tells the mail client how to display the parts. This is where the subtlety lives.
multipart/mixed — Sequential Parts
The most common multipart type. Parts are displayed in order. Used for "message body + attachments":
Content-Type: multipart/mixed; boundary="----=_mixed" ------=_mixed Content-Type: text/plain; charset=utf-8 Here's the report you requested. ------=_mixed Content-Type: application/pdf; name="report.pdf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="report.pdf" JVBERi0xLjQKJeLjz9MK... ------=_mixed--
multipart/alternative — Same Content, Different Formats
Contains multiple versions of the same content. The mail client picks the best one it can display. Parts are ordered from simplest to richest — the last part is preferred:
Content-Type: multipart/alternative; boundary="----=_alt" ------=_alt Content-Type: text/plain; charset=utf-8 Welcome to our service! ------=_alt Content-Type: text/html; charset=utf-8 <h1>Welcome to our service!</h1> <p>We're glad to have you.</p> ------=_alt--
This is how every well-formed HTML email works: the text/plain fallback comes first, the text/html version comes last. A client that supports HTML displays the HTML; a plaintext client displays the text.
multipart/related — Linked Parts
Used when parts reference each other. The most common use case is HTML email with inline images. The HTML references images by Content-ID (cid: URLs):
Content-Type: multipart/related; boundary="----=_rel" ------=_rel Content-Type: text/html; charset=utf-8 <p>Check out our logo:</p> <img src="cid:logo@example.com" alt="Logo" /> ------=_rel Content-Type: image/png Content-Transfer-Encoding: base64 Content-ID: <logo@example.com> iVBORw0KGgoAAAANSUhEU... ------=_rel--
multipart/digest — Collection of Messages
A variant of mixed where the default content type for each part is message/rfc822 instead of text/plain. Used by mailing list digests. Rarely seen in modern email.
Key Technical Details
Nesting Multipart Types
The real power of MIME comes from nesting. A typical marketing email with inline images and an attachment looks like this:
; The standard structure for HTML email with inline images + attachments Content-Type: multipart/mixed ← outer: body + attachments | |-- multipart/alternative ← body: text or HTML | |-- text/plain ← plaintext fallback | |-- multipart/related ← HTML + inline images | |-- text/html ← the HTML body | |-- image/png (cid:logo) ← inline image | |-- application/pdf (attachment) ← file attachment
This three-level nesting is the standard pattern used by virtually every email library and email service provider.
The message/rfc822 Type
Encapsulates an entire email message as a body part. Used for forwarding messages as attachments and in bounce notifications (RFC 3462 multipart/report). The encapsulated message has its own headers (From, To, Subject, etc.) and body.
The application/octet-stream Fallback
When the content type of a file is unknown, use application/octet-stream. This tells the client to treat it as generic binary data and typically triggers a download prompt. It is the MIME equivalent of "I don't know what this is; save it and figure it out yourself."
Boundary Requirements
The boundary string has specific rules:
- Maximum 70 characters.
- Composed of ASCII alphanumerics plus a limited set of special characters:
'()+_,-./:=?and space. - Must not appear in any enclosed body part.
- In practice, use a long random string like
----=_Part_12345_67890.1234567890.
Common Mistakes
-
Using
multipart/mixedinstead ofmultipart/alternativefor text+HTML. If you put text/plain and text/html in a mixed container, the client will display both (or display text and offer HTML as a download). Use alternative so the client picks the best format. -
Wrong part order in
multipart/alternative. Simplest format first, richest last. If you put HTML before plaintext, some clients will display the plaintext version even though HTML is available. -
Inline images without
multipart/related. If you reference acid:URL in HTML but the image is in a siblingmultipart/mixedpart instead of amultipart/relatedcontainer, many clients won't resolve the reference. -
Missing Content-ID angle brackets. The Content-ID header value must be wrapped in angle brackets:
<image001@example.com>. Thecid:reference in HTML omits them:src="cid:image001@example.com". -
Boundary collisions. Using a short or predictable boundary string (like
boundaryor---) risks appearing in the body content, which will corrupt the message structure. Always use random boundaries. -
Forgetting the final
--. The closing boundary must end with--(e.g.,--boundary--). Missing this causes parsers to wait for more parts and may result in a garbled or incomplete message.
Deliverability Impact
- Correct multipart/alternative is essential. Spam filters expect well-formed HTML emails to include a text/plain alternative. Missing it is a spam signal. The text and HTML parts should have roughly equivalent content — a one-line text part with a 50 KB HTML part looks suspicious.
-
Inline images increase spam score. Heavy use of
multipart/relatedwith many inline images (especially when the email is mostly images with little text) triggers image-spam heuristics. Prefer hosted images withhttps://URLs overcid:references for marketing email. -
Attachment types matter. Executable attachments (
.exe,.js,.bat) are blocked or quarantined by nearly all mail providers. Even.zipfiles containing executables will be flagged. Stick to safe types: PDF, common image formats, office documents. - Oversized messages bounce. Many providers reject messages over 25 MB (some over 10 MB). Remember that base64 encoding adds 33% overhead. A 20 MB attachment becomes a ~27 MB email.
- Properly structured MIME signals legitimacy. Well-formed MIME with correct nesting, valid boundaries, and proper Content-Type declarations tells spam filters this message was generated by legitimate email software, not a hand-crafted spam tool.