Content-Type and MIME Structure in Email: Multipart, Encodings and Boundaries (RFC 2045-2049)

Content-Type and MIME structure in email: the RFC 2045-2049 rules for multipart/alternative, multipart/mixed, multipart/related, and their nesting. Covers boundaries, character sets, the four Content-Transfer-Encodings (7bit, 8bit, quoted-printable, base64), why the plain-text alternative still matters in 2026, and the 10 mistakes that break email rendering in production.
Alaa
By Alaa
SMTPedia documents email infrastructure end to end: SMTP standards from the RFC archive, delivera...
13 min read Updated Aug 28, 2026 205 views

📩 Email headers series. This is the tactical guide to Content-Type, MIME structure, and encodings. For the RFC catalog and other header deep-dives, see the headers and MIME hub →

📎 Quick MIME reference

Every modern email is a MIME document. The Content-Type header at the top declares whether the body is plain text, HTML, a combination of both, or a message with attachments. Because base64 inflates every attached file on the way out, oversized payloads are usually better served by one of the alternatives to attaching the file at all. Multipart types nest bodies inside boundary-delimited sections. Encodings translate arbitrary bytes into 7-bit-safe text. Get the structure wrong and Gmail sends you to spam, or worse, shows a blank message.

SpecRFC 2045 to 2049 (MIME), RFC 5322 (message format)
Where declaredContent-Type: header at the top of the message
Simple typestext/plain, text/html
Multipart typesmultipart/alternative, multipart/mixed, multipart/related
Encodings7bit, 8bit, quoted-printable, base64
Plain-text requirementNot enforced, but heavily weighted by spam filters in 2026

MIME is what makes modern email possible. It is why you can send an HTML message with embedded images and a PDF attachment in one email, why non-ASCII text renders correctly on the receiving end, and why the same message can render as plain text on your terminal and as styled HTML in Gmail. The Content-Type header tells the receiving mail client how to interpret the body, and small mistakes in that declaration are the difference between a rendered inbox message and a wall of raw base64 that lands in spam.

What MIME is and why every email needs it

MIME (Multipurpose Internet Mail Extensions) is a set of five RFCs (2045 through 2049) that extend the original 1982 email format (RFC 822, now RFC 5322) to carry more than plain ASCII text. Before MIME, an email body was ASCII characters, 7-bit encoded, 998 characters per line maximum. After MIME, an email body can be text, HTML, images, PDF attachments, video, or any combination, encoded so that mail servers that only understand ASCII can still transport it safely.

Two headers do the work:

  • MIME-Version: 1.0: declares that the message uses MIME. Universally present in modern email.
  • Content-Type: ...: declares the type of the body. This is where all the interesting decisions live.

A third header, Content-Transfer-Encoding, declares how the body’s bytes are encoded for transport. Together, these three headers tell the receiver everything it needs to decode and render the body correctly.

The Content-Type header

The Content-Type header has a two-part media type (like text/html or multipart/alternative) plus optional parameters. Format:

Content-Type: type/subtype; param1=value1; param2=value2

The most common simple types:

TypeMeaning
text/plainPlain text body
text/htmlHTML body
image/jpeg, image/pngImage attachments
application/pdfPDF attachments
application/octet-streamGeneric binary (fallback for unknown types)

Simple types are used when the message has only one body: a plain-text-only email, or an attached PDF sent alone. Real transactional and marketing email almost always uses multipart types, because a modern email is not one body but several bodies that the client picks between.

The charset parameter

For text types, the charset parameter is mandatory in practice:

Content-Type: text/html; charset=utf-8

UTF-8 is the modern default. Older messages sometimes use ISO-8859-1 (Latin-1) or Windows-1252. Omitting the charset causes Gmail and Outlook to guess, and their guesses are often wrong for non-English text.

The three multipart types

multipart/alternative

Used when the message has multiple versions of the same content. The classic case: a plain-text version and an HTML version of the same email. The mail client picks the best one it can render (HTML if it supports it, plain text if not). Both versions must convey the same message; a client that shows the HTML version and the plain-text version simultaneously would show the recipient the message twice.

Structure:

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

----boundary-abc
Content-Type: text/plain; charset=utf-8

Plain text version here.
----boundary-abc
Content-Type: text/html; charset=utf-8

<html><body>HTML version here.</body></html>
----boundary-abc--

multipart/mixed

Used when the message has independent parts: a body plus one or more attachments. The client displays all parts (rendering the body, listing the attachments). Each attachment is a separate part with its own Content-Type and Content-Disposition.

Content-Type: multipart/mixed; boundary="--boundary-outer"

----boundary-outer
Content-Type: text/html; charset=utf-8

<html><body>See attached report.</body></html>
----boundary-outer
Content-Type: application/pdf; name="report.pdf"
Content-Disposition: attachment; filename="report.pdf"
Content-Transfer-Encoding: base64

JVBERi0xLjQKJcOkw7zDtsO...
----boundary-outer--

Used when the parts are logically bound: an HTML body plus the images referenced by <img src="cid:..."> tags inside it. The images are inline, not separate attachments; the client shows them rendered inside the HTML body.

Content-Type: multipart/related; boundary="--boundary-rel"

----boundary-rel
Content-Type: text/html; charset=utf-8

<html><body><img src="cid:logo1234"></body></html>
----boundary-rel
Content-Type: image/png
Content-ID: <logo1234>
Content-Transfer-Encoding: base64

iVBORw0KGgoAAAANSUhEUg...
----boundary-rel--

The full nesting for real production email

If you want to see what the text/html part looks like in practice, you can write and preview one in our email template editor.

A typical HTML email with inline images and a PDF attachment nests all three multipart types:

multipart/mixed
├── multipart/alternative
│   ├── text/plain
│   └── multipart/related
│       ├── text/html
│       └── image/png (inline logo, referenced as cid:)
└── application/pdf (real attachment)

The outer multipart/mixed holds the body plus attachments. Inside it, multipart/alternative gives the client a plain-text fallback. Inside the HTML alternative, multipart/related ties the HTML to its inline images. This is exactly what Gmail, Outlook, and every major ESP generate for HTML+attachment messages.

Boundaries

A boundary is a string that separates parts in a multipart message. It is declared as a parameter of the multipart Content-Type:

Content-Type: multipart/alternative; boundary="--boundary-abc-1234"

Inside the body, each part is preceded by -- followed by the boundary string. The final part is followed by --, the boundary string, and -- again to signal the end of the multipart section:

----boundary-abc-1234
Content-Type: text/plain

Part 1
----boundary-abc-1234
Content-Type: text/html

Part 2
----boundary-abc-1234--

The boundary string must not appear anywhere in any part’s body. If it does, the parts split at the wrong place and the message becomes malformed. Well-behaved generators use random 20+ character boundaries to make accidental collisions statistically impossible; some also add a component that could never appear in real content (like =_NextPart_ or a UUID).

Nested multipart messages need distinct boundaries: the outer multipart/mixed and the inner multipart/alternative cannot share a boundary string, or the parser cannot tell which level a boundary marker belongs to.

Content-Transfer-Encoding

SMTP historically only guaranteed transport of 7-bit ASCII with a maximum line length of 998 characters (per RFC 5321). Any content outside those constraints (binary data, long lines, non-ASCII text) must be encoded to pass safely. The Content-Transfer-Encoding header declares which encoding is in use:

EncodingWhat it doesUse case
7bitNo encoding, ASCII only, short linesPlain-text ASCII messages
8bitNo encoding, allows 8-bit charactersUTF-8 text over 8BITMIME-capable SMTP
quoted-printablePreserves ASCII, escapes non-ASCII as =XXUTF-8 text over any SMTP
base64Encodes bytes into 4-character alphabet groupsBinary attachments, some HTML
binaryNo encoding, allows arbitrary bytesRare, requires BINARYMIME extension

When to use which

  • Plain-text ASCII messages: 7bit. No encoding overhead.
  • UTF-8 text (most non-English content): quoted-printable. Slightly bulkier than 8bit but universally safe.
  • HTML with lots of ASCII characters (typical marketing email): quoted-printable. Preserves readability of the raw source for debugging.
  • Binary attachments (PDF, images, video): base64. Always. No alternative.

Modern SMTP servers universally support 8BITMIME, meaning 8bit works end-to-end for most senders. But older MTAs and some middleboxes still require 7bit-safe encoding, which is why quoted-printable remains the default for UTF-8 text.

The encoding choice has a size consequence as well as a rendering one: what base64 does to an attachment’s size is why a file comfortably under the stated limit can still be refused at the door.

Why the plain-text part still matters in 2026

Modern mail clients render HTML by default. Almost no one reads plain text in their inbox. So why does every serious email still include a plain-text alternative in the multipart/alternative block?

Three reasons:

  1. Spam filter signal. Every major spam filter (Gmail, Microsoft, Barracuda, Proofpoint) treats messages without a plain-text alternative as slightly suspicious. The reasoning: legitimate senders bother; spammers often do not. It is not a hard rule, but it accumulates with other signals to push you into the promotions tab or spam folder.
  2. Accessibility. Screen readers and text-only mail clients (still common in developer and technical environments) render the plain-text version when available. HTML-only messages read poorly through assistive technology.
  3. Preview snippets. Gmail and Outlook generate the message preview snippet (the line of text visible in the inbox list) from the plain-text part when present. Without a plain-text version, they extract from the HTML, which often produces awkward snippets full of CSS or hidden preheader text.

Rule of thumb: every HTML message should include a plain-text alternative that carries the same essential content. Do not use the plain-text version as an afterthought or a stub; treat it as a first-class rendering that a real recipient might read.

How to inspect the raw MIME source

Gmail

Open the message, three-dot menu, “Show original”. The raw MIME source appears with all headers and body parts.

Outlook (web)

Open the message, three-dot menu, “View message source”.

Outlook (desktop)

Open the message in its own window, File → Properties. The “Internet headers” box shows headers only; to see the body, save the message as an .eml file and open with a text editor.

Command line

cat /var/mail/username | less
formail -s procmail -f - < message.eml

Programmatically

Use Python’s email.message_from_bytes(), PHP’s imap_fetchheader() plus imap_fetchbody(), or Node’s mailparser package. Every mainstream language has a MIME parser in its standard library or a widely-used package.

10 common Content-Type and MIME mistakes

  1. No MIME-Version: 1.0 header. Some receivers refuse to parse multipart bodies without it, treating the message as a single plain-text body.
  2. Boundary string appears inside a part’s body. Splits the message at the wrong place, corrupting parts. Use a 20+ character random boundary.
  3. Charset declared but content is a different charset. Declaring charset=utf-8 and sending Windows-1252 bytes renders as mojibake on the receiver.
  4. No text/plain alternative in an HTML message. Reduces deliverability, breaks previews, hurts accessibility.
  5. Wrong Content-Transfer-Encoding for the actual content. Declaring 7bit when the body contains UTF-8 characters causes truncation or replacement at any 8bit-unclean hop.
  6. Missing Content-Disposition on attachments. Mail clients need it to know whether to display inline or offer as download.
  7. Inline image not referenced correctly. The <img src="cid:..."> value must match the Content-ID (without the angle brackets) of the image part.
  8. Nested multipart with reused boundaries. Inner and outer boundaries must be distinct.
  9. Base64 lines longer than 76 characters. RFC 2045 requires 76-character lines for base64. Some MTAs reject or truncate longer lines.
  10. Missing final boundary marker. The multipart section must end with the boundary string followed by --. Omitting it causes some parsers to treat the last part as truncated.

Content-Type and MIME FAQ

Do I really need to include a plain-text version in every HTML email?

Yes. Every major spam filter treats HTML-only messages as slightly suspicious. Gmail and Outlook generate preview snippets from the plain-text part when available. Screen readers and text-only mail clients render the plain-text version. The cost of including one is negligible, and the benefit is measurable in deliverability and accessibility.

What is the difference between multipart/alternative and multipart/mixed?

Alternative parts represent the same content in different formats (plain text and HTML of the same message); the client picks one to display. Mixed parts represent independent content (a body plus attachments); the client displays all of them. A real HTML email with an attachment nests both: an outer multipart/mixed for the body-plus-attachment structure, and an inner multipart/alternative for the plain-text and HTML versions of the body.

Should I use quoted-printable or base64 for HTML content?

Quoted-printable for HTML with mostly ASCII characters (the common case for English-language marketing email). It keeps the raw source readable for debugging and adds minimal overhead. Base64 for HTML that contains lots of non-ASCII characters or when you need to protect the exact byte sequence (rare for HTML). Never use 7bit for HTML that contains any accented or non-Latin characters.

How do inline images work in emails?

Inline images are attached as separate parts inside a multipart/related block alongside the HTML body. Each image has a Content-ID header, and the HTML references it via <img src="cid:the-content-id">. The client resolves the cid: URL to the matching image part and renders it inline. This is different from remote images (<img src="https://...">), which are downloaded from a server when the recipient opens the message.

Why does my email arrive as raw text with weird characters like =E2=80=99?

The message was encoded quoted-printable, but the receiving client did not decode it. The =XX sequences are hex bytes representing non-ASCII characters. The usual cause: a missing or wrong Content-Transfer-Encoding header, or a broken client. Verify that your message includes Content-Transfer-Encoding: quoted-printable when the body contains encoded characters.

What happens if my boundary string is not unique?

If the boundary string accidentally appears inside a part’s body, the parser splits the message at that point instead of at the intended boundary. The result: broken parts, missing content, or a message that fails to render entirely. Generators use long random strings (20+ characters plus a signature like =_NextPart_) to make accidental collisions statistically impossible.

Final words

MIME is one of those specifications that everyone leans on and few people read closely. Every mail library abstracts the details, and the abstractions usually work. Where they fail is at the edges: unusual charsets, deeply nested multipart structures, boundaries that collide with content, or Content-Transfer-Encoding mismatches. Those bugs cascade into malformed messages, spam-folder placements, and mysterious rendering failures.

The mental model to keep: Content-Type declares what the body is, Content-Transfer-Encoding declares how it is packed for transport, boundaries separate the parts of a multipart body, and MIME-Version declares the whole thing is MIME. Get those four things right and modern mail infrastructure does the rest.

For related headers and encoding topics, see our guides on the RFC 5322 message format, the Message-ID header, the Received chain, and the Authentication-Results header.

A perfect MIME structure means nothing if the address bounces.

SMTPing catches disposables, role-based, catch-all, syntax errors, dead mailboxes and traps before your carefully-encoded multipart lands in a suppression list. 13 validation types, 25 free daily.

Try SMTPing →

About the Author

Alaa - SMTPedia author

Alaa · LinkedIn

Email infrastructure specialist with 8+ years of hands-on experience in SMTP, deliverability, and email verification. I’ve configured and troubleshot mail systems across Postfix, Exchange, and cloud relays, managed IP reputation and warmup campaigns, and built verification pipelines processing millions of addresses. My work spans DNS authentication (SPF, DKIM, DMARC, BIMI), bounce handling, blocklist monitoring, and compliance frameworks including CAN-SPAM and GDPR. I write every article on SMTPedia to give email professionals, developers, and marketers the accurate, RFC-grounded reference they need.


About SMTPedia

SMTPedia is an independent email industry reference covering SMTP, IMAP, POP3, email deliverability, marketing platforms, DNS authentication, and email verification. Every article is researched from official provider documentation, IETF RFCs, and industry best practices. Settings and configurations are verified quarterly.

We are cited as a source by ChatGPT, Microsoft Copilot, and thousands of email professionals worldwide. Learn more about our editorial process.