WSS
Web Specification Studio Home
On this page
FoundationsRequiredUpdated

MIME Multipart Message Structure

Structure rich email payloads using standardized MIME multipart trees (alternative, related, mixed), paired plain-text fallbacks, and collision-resistant boundary delimiters.

What it is

Multipurpose Internet Mail Extensions (MIME), defined in RFC 2045 through RFC 2049, extends the basic RFC 5322 text message format to support multiple character sets, rich HTML formatting, inline multimedia images, and binary file attachments.

MIME organizes complex email content using a nested hierarchical tree structure of multipart content types:

multipart/mixed (Root container if attachments exist)
├── multipart/related (HTML body + embedded inline images)
│   ├── multipart/alternative (Plain text fallback + HTML)
│   │   ├── text/plain (Plain text version for text clients & watches)
│   │   └── text/html (Styled HTML email markup)
│   └── image/png (Inline header logo referenced via cid:[email protected])
└── application/pdf (Attached invoice document)

Why it matters

  • Accessibility & Device Support: Smartwatches (Apple Watch, Wear OS), screen readers, and low-bandwidth clients render the text/plain portion. Omitting the plain text part degrades user experience on wearable devices and triggers spam filter penalties.
  • Reliable Image Rendering: Remote images (<img src="https://...">) are blocked by default in many enterprise mail clients (Outlook desktop, Thunderbird). Embedding critical visual assets (such as corporate brand marks) as inline MIME parts with Content-ID and Content-Disposition: inline allows them to render without triggering security warnings.
  • Parser Robustness: Malformed multipart boundaries cause mail clients to render raw MIME headers as plain text or fail to display attachments altogether.

How to implement

1. Generate collision-resistant boundary strings. Boundary strings must be unique sequences of characters that cannot appear within the body of any nested part. Prefix boundaries with a standard prefix and a cryptographic random token:

Content-Type: multipart/alternative; boundary="=_Part_89342_a9f73b9e1c"

2. Order parts in multipart/alternative from least to most specialized. RFC 2046 §5.1.4 explicitly mandates that parts inside multipart/alternative MUST be ordered in increasing order of complexity:

  1. First part: text/plain; charset=utf-8
  2. Second part: text/html; charset=utf-8

Email clients parse the list and display the last format they support. Placing text/html before text/plain will cause modern email clients to render plain text instead of HTML.

3. Reference inline images via cid: URIs. To embed inline assets without external HTTP requests:

  1. Attach the image inside a multipart/related container with a unique Content-ID enclosed in angle brackets:
    --=_Part_related_01
    Content-Type: image/png; name="logo.png"
    Content-Transfer-Encoding: base64
    Content-ID: <[email protected]>
    Content-Disposition: inline; filename="logo.png"
    
    iVBORw0KGgoAAAANSUhEUgAA...
  2. Reference the Content-ID inside your HTML <img> tag:
    <img src="cid:[email protected]" alt="Company Logo" width="200" height="50">

4. Terminate boundaries correctly.

  • Inner boundaries begin with -- followed by the boundary string: --=_Part_89342_a9f73b9e1c\r\n
  • The terminal closing boundary must append -- at both the beginning and the end: --=_Part_89342_a9f73b9e1c--\r\n

Common mistakes

  • Missing Plain-Text Alternative: Sending HTML-only emails (Content-Type: text/html as the root body). This raises spam scores in SpamAssassin and breaks accessibility on smartwatches.
  • Inverted Alternative Part Order: Putting text/html before text/plain, causing desktop and mobile email clients to display raw unstyled plain text.
  • Missing Terminal Boundary --: Omitting the closing --boundary-- tag causes receiving parsers to buffer indefinitely waiting for stream termination.
  • Forgetting MIME-Version: 1.0 in the Root Headers: Every MIME-compliant email must declare MIME-Version: 1.0 in the top-level RFC 5322 header section.

Verification

1. Inspect the MIME tree structure using standard diagnostic utilities:

# Python one-liner to dump MIME part structure
python3 -c "
import email, sys
msg = email.message_from_bytes(open('test_email.eml', 'rb').read())
for part in msg.walk():
    print(part.get_content_type(), part.get_charsets(), part.get_filename())
"

2. Verify rendering across diverse clients: Send test messages to Gmail, Apple Mail (iOS/macOS), Microsoft Outlook (Windows/Web), and Thunderbird to confirm both HTML rendering and plain-text fallback behavior.

Related topics

Sources & further reading