Every HTML email carries a second version almost nobody edits. How multipart nesting works, what breaks inside it, and why the text part still earns its place.
Every HTML email you send contains a second, older version of itself that nobody on the team has read. The plain-text alternative is generated by the sending platform, inherited from a template written years ago, or replaced with a single line telling recipients to view the message in a browser. It is the version that renders on a watch notification, in a screen reader, in a text-mode client, and in the preview pane of several corporate gateways, and it is one of the inputs content filters weigh most heavily. Understanding the container it lives in is the difference between fixing it once and regenerating the same defect on every send.
The container, from the outside in
A modern campaign is a nested structure rather than a flat one. The outermost container is multipart/mixed when attachments are present, holding the message body and each attached file as siblings. Inside it sits multipart/related, binding the HTML to any images embedded by content ID rather than fetched over the network. Inside that sits multipart/alternative, holding the same content in two or more formats and declaring them equivalent. Order inside multipart/alternative is significant and frequently gets reversed by hand-rolled senders: parts appear least-preferred first, so text/plain comes before text/html, and a conforming client renders the last part it understands.
1multipart/mixed
2 +-- multipart/related
3 | +-- multipart/alternative
4 | | +-- text/plain (least preferred, therefore listed first)
5 | | +-- text/html (preferred, therefore listed last)
6 | +-- image/png (Content-ID: <logo>, referenced by cid:)
7 +-- application/pdf (the attachment)Where the structure breaks
Three failures account for most of what goes wrong. The first is inverted ordering inside multipart/alternative, which causes conforming clients to render the plain-text version of a carefully designed campaign, and it survives testing because the popular webmail clients tolerate it. The second is boundary mismanagement: a boundary string that also appears in the content, a missing terminating boundary, or CRLF line endings replaced with bare newlines by a well-meaning templating layer, each of which produces a message some parsers treat as one malformed blob. The third is encoding, where a quoted-printable body carrying unencoded high-bit characters, or a line exceeding 998 octets, triggers rejection at strict receivers. None of these appear in a sending platform's preview, and all of them are obvious in the raw source.
Writing the text part on purpose
What a real plain-text alternative looks like
- The same substance as the HTML, written for reading, not a stub pointing at a web version
- URLs written in full on their own line, since there is no anchor text to carry them
- Lines wrapped at 72 to 78 characters, well inside the 998-octet limit
- Structure carried by blank lines and simple headings rather than by markup or ASCII art
- The unsubscribe URL present and working, not only in the HTML part
- Tracking-parameter bloat kept out, because raw query strings dominate a text message visually
- Generated from source content, not by stripping tags out of the rendered HTML
The economics here are unusually favourable. A plain-text alternative is written once per template rather than once per campaign, it costs about an hour, and it removes a cluster of structural filter penalties while improving the experience for the readers hardest to reach any other way. Set that against the recurring cost of subject-line optimisation and the ranking is obvious. The reason it stays undone is that nobody on the team ever sees it, which is exactly why it belongs in the template review rather than in the campaign checklist.
Frequently Asked Questions
Can I send HTML only?
Does the plain-text part need to match the HTML exactly?
Are auto-generated text parts good enough?
Where does an AMP part fit?
Key Takeaways
- Message bodies nest: multipart/mixed holds attachments, multipart/related binds inline images, multipart/alternative holds formats
- Parts inside multipart/alternative run least-preferred first, so text/plain precedes text/html
- Most structural faults are ordering, boundary handling, and encoding, and none show up in a rendering preview
- The plain-text part is read by watches, screen readers, and filters, and deserves writing rather than generating
- Fix it once at template level instead of regenerating the same defect on every campaign
Related articles

Backscatter: The Bounces You Never Sent
When spammers forge your domain as their envelope sender, the bounces come to you. What backscatter is, why it happens, and how to stop causing and receiving it.

DMARCbis Is Published: What RFC 9989 Changes
After eleven years, DMARC is a real standard: RFC 9989, 9990, and 9991 replace RFC 7489. What is different, what stays, and the short list of actions for senders.

Subaddressing: What Plus Addresses Tell Senders
user+anything@gmail.com is one mailbox wearing labels. How subaddressing works, why blocking it backfires, and what plus addresses reveal about your data flows.


