Message formats and rendering

multipart/alternative on mobile: examples and pitfalls

Mobile clients pick one multipart/alternative part—usually HTML when present. Build sane text parts and avoid relying on a single raw MIME tree.

Smartphone silhouette with offset plain and HTML paper layers as MIME parts

A mobile email client faced with multipart/alternative will typically show a single part—nearly always the HTML part when one exists—not a merge of all siblings. If your text/plain part is empty, nonsense, or missing the action URL, users who prefer plain text (or whose HTML is blocked) get a broken experience. Build both parts deliberately; test on real mobile clients; do not assume desktop Outlook behavior matches iOS Mail or Gmail Android.

Receive-only previews such as Mailby Quick Inbox help you inspect parts safely during development of systems you own, but they are not identical to every mobile client’s renderer.

Mobile client context

Constraints vs desktop:

  • Smaller screens encourage HTML layout hacks that explode in plain text
  • Data savers may block remote images
  • Some corporate MDMs strip HTML
  • Dark mode recolors HTML unpredictably

multipart/alternative per MIME means “these parts are equivalent; pick one.” Order conventionally goes from simplest to richest (text/plain then text/html). Clients may still prefer HTML regardless of order—verify, do not mythologize.

Fixture thinking

Minimal valid alternative

  • Part 1: text/plain; charset=utf-8 with the reset URL alone on a line
  • Part 2: text/html; charset=utf-8 with the same URL in an <a href>

Working path: iOS Mail shows HTML; a text-only accessibility path still has the URL.

Intentionally broken fixture

  • HTML contains the button
  • text/plain says “Please view this message in HTML”

Failure: User with HTML disabled cannot act. This still ships in the wild.

Observation table

Raw partDeclared typeObserved rendering (typical mobile)Accessibility/security implication
Body Atext/plainShown if no HTML or user settingMust include actionable URL
Body Btext/htmlDefault in most mobile MUAsXSS/remote content risk
Nested relatedmultipart/relatedHTML + inline CID imagesBroken images if CID missing
Spurious attachmentapplication/octet-streamAttachment railUsers fear malware

Pitfalls

  1. Empty text part generated by ESP “HTML only” modes
  2. Different URLs in text vs HTML (tracking variants)—confuses audits and users
  3. CSS that hides the only CTA
  4. Relying on <meta refresh> or scripts—blocked
  5. Assuming multipart/mixed vs alternative interchangeably

Worked example for engineers

  1. Construct a message with intentional mismatch URLs in text vs HTML.
  2. Open in iOS Mail, Gmail Android, and a safe desktop preview.
  3. Record which URL was tappable.
  4. Fix pipeline so generators share one canonical URL variable.
  5. Add a CI assert: plain and HTML both contain the same host + path.

Use Mailby preview when you need a quick MIME sanity check without exposing your personal mailbox to staging spam (/inbox). For automated authorized captures, /developers.

Security notes

HTML email is an attacker favorite. Prefer text for security-sensitive messages when possible; if HTML is required, keep CSS simple and links absolute to known hosts. QR-only HTML without text falls into the safety issues covered in our QR reset guide.

Alternatives and durable mail

Rendering bugs are about MIME, not whether the mailbox is temporary. Durable mailboxes still need correct parts. Temporary inboxes help QA isolation.

Short answers

What causes multipart/alternative issues on mobile?
Missing/weak text parts, client HTML preference, and generator mismatches.

What should I do first?
Inspect raw MIME; ensure text/plain carries the action.

When is a permanent address safer?
Unrelated—use durable mail for real accounts; use any receive path for MIME QA.

What evidence changes the recommendation?
Client documentation stating explicit part-selection rules for your target MUA version.

Sources and limitations

  • MIME: RFC 2046 on multipart/alternative
  • Client behavior changes; retest on 2026-09-24 device matrix
  • Mailby preview ≠ full iOS WebKit mail UI

Deeper: nested structures

multipart/mixed containing an alternative subtree plus attachments is common. Mobile UIs may surface attachments separately while picking HTML from the alternative group. Test with a calendar invite + HTML body to see dual surfaces.

Dark mode

CSS prefers-color-scheme support varies; transparent PNGs vanish. Plain text remains readable—another reason to invest in the text part.

AMP and experimental parts

Additional alternative parts (AMP for Email) are not universally supported. Never put the only security code exclusively in an exotic part.

QA checklist

  • text/plain includes URL
  • HTML includes same URL
  • No scripts required
  • Images optional
  • Tested on iOS + Android primary clients
  • Previewed in receive-only tool

Extended operational notes

Treat this section as the practical appendix that turns a short briefing into something you can run under pressure. The goal is not filler; it is the set of reminders teams usually rediscover after an outage or a confused stakeholder thread.

Pre-change capture

Before you touch production-adjacent settings, capture the current state into the ticket: screenshots of DNS panels, dig outputs with timestamps, application config hashes, and the names of the humans on call. When the fix works, you will want that baseline to explain what changed. When the fix fails, you will need it to roll back without guesswork.

Communication template

Post a short status to your engineering channel: symptom, blast radius, current hypothesis, next check, and ETA for the following update—even if the ETA is “in 20 minutes.” Silence creates duplicate debugging. Include whether customers are impacted or only staging.

External vantage points

Test from at least two networks you do not control (home broadband, mobile data, or a VPS in another region). Corporate egress filtering regularly lies to you about port 25 and about DNS recursion. A false “it works on VPN” has wasted more hours than almost any MIME nuance.

Customer messaging

If outsiders are affected, publish honest status text: what failed, what to retry, and whether mail will be replayed. Do not promise recovery of messages you cannot recover. Temporary infrastructure without retention guarantees should never be described as a durable archive in status pages.

Post-incident review prompts

  • What signal would have caught this in five minutes?
  • Which runbook step was missing or wrong?
  • Did we have ownership for DNS vs app vs ESP clearly assigned?
  • Were TTLs too high for the risk of the change?
  • Did anyone debug the wrong layer first, and how do we prevent that habit?

Training reps

Quarterly, recreate a staging failure intentionally (authorized chaos): wrong MX in a sandbox zone, empty text/plain part, expired OTP TTL, purged temporary inbox mid-QA. Muscle memory beats wiki pages written once and never read.

Tooling shortlist

Keep a known-good set of commands and accounts documented: dig/drill, openssl s_client, a throwaway outbound sender you control, a receive-only inspector such as Mailby Quick Inbox for MIME peeks on systems you own, and access to your ESP’s event logs. Replace tribal SSH lore with links in the runbook.

Security and authorization reminder

Only test systems you are allowed to test. Do not use verification techniques as a pretext to probe third parties. Logging and retention policies still apply during incidents; do not paste customer message bodies into public Slack channels.

Product-truth recap for Mailby mentions

Mailby remains receive-only: no send, no forward, no open relay, no anonymity guarantee, no claim of universal deliverability. Quick Inbox is live at /inbox. Privacy Pro is live via /pricing. Developer Test Inbox Cloud is live at /developers and /account/developer. Encryption is at rest plus TLS in transit—not E2EE. Retention differs from address lease—read /data-retention before promising timelines to users.

Closing bridge

If you only remember one habit from this appendix, make it this: establish the failing layer with evidence before changing two systems at once. Parallel unscientific edits create myths (“restarting the app fixed DNS”) that haunt the next deploy.

Appendix note 1

Re-verify live configuration on the day you act; screenshots in this article are narrative composites dated 2026-09-24 and may not match your vendor UI.

Extended operational notes

Treat this section as the practical appendix that turns a short briefing into something you can run under pressure. The goal is not filler; it is the set of reminders teams usually rediscover after an outage or a confused stakeholder thread.

Pre-change capture

Before you touch production-adjacent settings, capture the current state into the ticket: screenshots of DNS panels, dig outputs with timestamps, application config hashes, and the names of the humans on call. When the fix works, you will want that baseline to explain what changed. When the fix fails, you will need it to roll back without guesswork.

Communication template

Post a short status to your engineering channel: symptom, blast radius, current hypothesis, next check, and ETA for the following update—even if the ETA is “in 20 minutes.” Silence creates duplicate debugging. Include whether customers are impacted or only staging.

External vantage points

Test from at least two networks you do not control (home broadband, mobile data, or a VPS in another region). Corporate egress filtering regularly lies to you about port 25 and about DNS recursion. A false “it works on VPN” has wasted more hours than almost any MIME nuance.

Customer messaging

If outsiders are affected, publish honest status text: what failed, what to retry, and whether mail will be replayed. Do not promise recovery of messages you cannot recover. Temporary infrastructure without retention guarantees should never be described as a durable archive in status pages.

Post-incident review prompts

  • What signal would have caught this in five minutes?
  • Which runbook step was missing or wrong?
  • Did we have ownership for DNS vs app vs ESP clearly assigned?
  • Were TTLs too high for the risk of the change?
  • Did anyone debug the wrong layer first, and how do we prevent that habit?

Training reps

Quarterly, recreate a staging failure intentionally (authorized chaos): wrong MX in a sandbox zone, empty text/plain part, expired OTP TTL, purged temporary inbox mid-QA. Muscle memory beats wiki pages written once and never read.

Tooling shortlist

Keep a known-good set of commands and accounts documented: dig/drill, openssl s_client, a throwaway outbound sender you control, a receive-only inspector such as Mailby Quick Inbox for MIME peeks on systems you own, and access to your ESP’s event logs. Replace tribal SSH lore with links in the runbook.

Security and authorization reminder

Only test systems you are allowed to test. Do not use verification techniques as a pretext to probe third parties. Logging and retention policies still apply during incidents; do not paste customer message bodies into public Slack channels.

Product-truth recap for Mailby mentions

Mailby remains receive-only: no send, no forward, no open relay, no anonymity guarantee, no claim of universal deliverability. Quick Inbox is live at /inbox. Privacy Pro is live via /pricing. Developer Test Inbox Cloud is live at /developers and /account/developer. Encryption is at rest plus TLS in transit—not E2EE. Retention differs from address lease—read /data-retention before promising timelines to users.

Closing bridge

If you only remember one habit from this appendix, make it this: establish the failing layer with evidence before changing two systems at once. Parallel unscientific edits create myths (“restarting the app fixed DNS”) that haunt the next deploy.

Appendix note 2

Re-verify live configuration on the day you act; screenshots in this article are narrative composites dated 2026-09-24 and may not match your vendor UI.

Conclusion

Mobile clients choose; they do not synthesize. Give them two honest equivalents under multipart/alternative, verify with real devices, and keep security actions visible in text. Use /inbox as a MIME inspection convenience while you build—not as proof every phone will agree.

Try it on Mailby

Open a receive-only disposable inbox when a short-lived address fits the job — session-bound, with timed purge.