Multipart Email: A Practical MIME Implementation Guide
A developer-focused guide to structuring multipart email so plain text, HTML, attachments, and inline resources survive real sending and receiving systems.
Overview
Multipart email uses MIME containers to carry more than one representation or resource in a single message. The common case is multipart/alternative with a text/plain version followed by a text/html version of the same content. Attachments usually require an outer multipart/mixed container, while HTML that depends on inline resources can use multipart/related. The reliable implementation is a MIME tree with explicit relationships—not a flat list of text, HTML, images, and files.
Most applications should provide semantic inputs to a maintained email library or provider SDK and let it create boundaries, fold headers, and encode body parts. You still need to understand the resulting tree: provider abstractions can be misused, and the raw received message is the evidence when a client shows the wrong body, exposes an attachment unexpectedly, or drops an inline image.
Choose a MIME container by the relationship between parts
The multipart subtype tells a recipient how sibling parts relate. In multipart/alternative, each child communicates the same information in a different representation. RFC 2046 orders those representations by increasing preference, with the richest preferred representation normally placed last; for typical email that means text/plain first and text/html second. A client can then choose the last format it supports rather than rendering both.
Multipart/mixed has different semantics: its children are independent items intended to be presented in order, which makes it the usual outer container for a body plus attachments. Multipart/related groups a root document with resources needed to display it, such as HTML and a content-ID image. Picking the wrong subtype can make a client show both alternatives, treat an inline asset as a downloadable file, or hide the intended body.
- Use alternative only when the children convey the same message
- Place text/plain before text/html inside multipart/alternative
- Use mixed for files the recipient should receive independently
- Use related only when a body part depends on the grouped resources
| Container | Relationship | Typical email use |
|---|---|---|
| multipart/alternative | Equivalent representations | Plain-text and HTML versions of one message |
| multipart/mixed | Independent ordered parts | Message body followed by one or more attachments |
| multipart/related | Root content plus dependent resources | HTML that references inline images by Content-ID |
Nest the MIME tree instead of flattening every part
A message with plain text, HTML, and a PDF is normally an outer multipart/mixed message. Its first child is a multipart/alternative container holding text/plain and text/html; its second child is the PDF attachment. The attachment is not another alternative because it does not communicate the same complete content as the message body.
If the HTML references an inline logo, the tree needs another relationship. One practical shape is outer multipart/mixed, then multipart/alternative for the body choices, with the HTML choice represented by a multipart/related container that includes the HTML root and its inline asset. MIME consumers differ at the edges, so use the shape generated by a proven library and confirm it in your target clients rather than hand-assembling a novel nesting order.
- Write down which parts are equivalent bodies, dependent resources, and independent attachments.
- Create the innermost body relationship first: usually text/plain and text/html alternatives.
- Group HTML-dependent resources with the HTML root when inline content is necessary.
- Wrap the completed body and independent files in multipart/mixed.
- Serialize with an email library, then inspect the received raw source.
| Requirement | Recommended shape | Common mistake |
|---|---|---|
| Plain text plus HTML | alternative(text, html) | Two unrelated top-level body parts |
| Plain text, HTML, and PDF | mixed(alternative(text, html), pdf) | Putting the PDF inside alternative |
| HTML with inline image | related(html, image) | Remote URL marked as a MIME attachment |
| Alternatives, inline image, and PDF | Nested mixed, alternative, and related containers | One flat mixed list with ambiguous roles |
Keep the plain-text and HTML versions equivalent
The plain-text part is not a teaser that says 'view this email in HTML.' It should carry the same essential message, links, sender identity, and unsubscribe or preference controls as the HTML part. It may use simpler structure—headings as lines, readable full URLs, and compact spacing—but a recipient choosing text/plain should not lose the call to action or compliance path.
Generate both alternatives from one content model when possible. If the HTML template and text body are edited separately, they drift: prices differ, a link disappears, or one version retains obsolete legal copy. Store and version the source data, render both outputs in the same build step, and fail pre-send checks when required links or identifiers appear in only one representation.
- Preserve the same promise and primary action in both versions
- Include human-readable link context in plain text
- Keep unsubscribe and sender information available without HTML
- Do not mechanically strip tags and assume the result is readable
- Version both rendered alternatives with the campaign or template
Let a library own boundaries, encoding, and part headers
Every multipart container needs a boundary parameter whose delimiter does not occur in its enclosed data. Each body part has its own Content-Type and may have a Content-Transfer-Encoding. RFC 2045 defines the MIME framing and transfer encodings used to move content safely through mail transport. These details are easy to get subtly wrong: line endings, boundary closure, header folding, non-ASCII text, and base64 wrapping can all produce a message that one parser accepts and another truncates.
Use a maintained MIME composer instead of string concatenation. Pass it Unicode text, HTML, filenames, media types, and disposition intent; do not pre-base64 content unless the library explicitly asks for it. For an attachment, provide a truthful media type and safe display filename. For an inline resource, assign a unique Content-ID and make the HTML cid: reference match it exactly. Never put user-supplied header text directly onto the wire without the library's validation because newline characters can turn data into injected headers.
- Do not reuse a handwritten static boundary across messages
- Do not encode content twice
- Sanitize filenames and reject CR/LF in user-controlled header values
- Keep attachment size policy outside the MIME serializer and enforce it before enqueueing
| Concern | Application supplies | MIME library should handle |
|---|---|---|
| Text and HTML | Unicode content and declared charset intent | Transfer encoding and line formatting |
| Multipart boundary | Container relationships | Unique boundary generation and closing delimiters |
| Attachment | Bytes, media type, safe filename, disposition | Encoding and header serialization |
| Inline resource | Bytes, media type, unique Content-ID | Encoding and MIME part construction |
Test the message after transport, not only before it
A local snapshot proves what your application attempted to create. It does not prove what arrived. Providers may add tracking, rewrite links, insert headers, or transform content; gateways may scan attachments; clients choose different alternatives. Send fixtures through the production-like path to controlled mailboxes, download the raw received source, and compare its MIME tree with the intended structure.
Build a compact fixture matrix: text and HTML only; each representation independently readable; one PDF attachment; one inline image; Unicode subject, body, and filename; a long URL; an empty optional field; and a message near your own size limit. Verify visible rendering, attachment behavior, content IDs, links, reply behavior, authentication results, and that the plain-text version can be selected or extracted.
- Reject malformed output before it enters a retry queue
- Test with images disabled and with the HTML part unavailable
- Open attachments in a safe test environment and verify their hashes before and after transport
- Keep fixture messages free of customer data
- Parse the serialized message with a second MIME parser in automated tests.
- Assert container types, child order, charsets, dispositions, filenames, and Content-IDs.
- Round-trip representative fixtures through the real provider or SMTP path.
- Inspect raw source in multiple receiving systems and compare the visible result.
- Repeat tests when the template engine, MIME library, provider, or tracking layer changes.
Make multipart structure part of the sending contract
Document what your application promises the provider: whether the SDK accepts separate text and HTML fields, whether it composes raw MIME, how attachments are passed, what it does with inline images, and whether tracking modifies the HTML after composition. Store a template version and message identifier with each send so a malformed message can be traced to the renderer, library, and provider configuration that produced it.
Mailbase's relevant connection is at this workflow boundary. Teams can create MJML campaigns and templates, run pre-send checks, schedule durable sends, and inspect delivery or reply events. MIME serialization still belongs to the rendering and provider path. If you connect Mailbase to useSend or another sending system, verify the final received multipart message whenever that path, its SDK, or its tracking behavior changes.
- Pin and review MIME-library changes like other infrastructure dependencies
- Retest after enabling click tracking or changing providers
- Log structure and identifiers, not sensitive body or attachment content
- Keep rendering failures separate from provider delivery retries
| Owner | Responsibility | Evidence |
|---|---|---|
| Content/template | Equivalent text and HTML, required links | Versioned render fixtures |
| Application | Correct relationships and safe attachment inputs | Parsed MIME-tree tests |
| Library/provider | Standards-based serialization and transport | Raw sent and received samples |
| Email operations | Client QA and change monitoring | Seed-test checklist and incident notes |
Common Mistakes
- Choosing a tool before deciding who owns deliverability.
- Treating DNS authentication as a one-time checkbox instead of an operating baseline.
- Mixing product-critical transactional email with experimental marketing sends, with no clear boundary.
- Trusting headline metrics (like open rate) that privacy proxies now inflate.
Sources & Further Reading
Official docs for current setup details, pricing, and API behavior — verify specifics there, since they change.
Related guides
More on multipart email and the surrounding email infrastructure workflow:
FAQ
What is a multipart email?
A multipart email is a MIME message whose body contains multiple parts. The parts may be equivalent representations such as plain text and HTML, independent items such as attachments, or a root document and dependent inline resources.
What is the correct order for plain text and HTML email parts?
Inside multipart/alternative, place text/plain first and text/html second. RFC 2046 defines the alternatives in increasing order of faithfulness so a recipient can choose the last representation it supports.
What is the difference between multipart/alternative and multipart/mixed?
Multipart/alternative contains different representations of the same information, while multipart/mixed contains independent ordered parts. A body with an attachment commonly uses mixed outside and an alternative text-and-HTML body inside.
Should developers build raw MIME strings by hand?
Usually no. Use a maintained MIME library or a provider SDK that accepts structured text, HTML, attachment, and inline-resource inputs. Then parse and inspect the serialized and received message so the abstraction remains testable.
Do multipart emails need a plain-text part?
For a message offering both HTML and text representations, a meaningful text/plain alternative improves compatibility, accessibility, debugging, and recipient choice. It should preserve the essential content, links, sender identity, and opt-out controls rather than merely pointing to the HTML version.