Message formats and rendering
Inline images in mobile email clients: examples and pitfalls
Mobile clients often block or detach CID inline images—build multipart fixtures deliberately, test with images off, and keep critical content in text.

Inline images in a mobile email client succeed only when the HTML references parts the client will load—CID/multipart/related attachments, remote URLs the client permits, or neither if the user disabled images. Critical information (OTPs, legal text, expiry times) must remain in plaintext or non-image HTML. Pretty banners are optional; codes are not.
This teardown builds a minimal fixture mindset and names the failure modes that show up on phones.
Mobile client context
Mobile MUAs (iOS Mail, Gmail app, Outlook mobile, etc.) differ on:
- Auto-loading remote images (privacy)
- Rendering
cid:linked parts - Downloading “related” attachments automatically on cellular
- Dark mode CSS filters that wreck image contrast
- Proxying images through vendor caches
Mailby’s web inbox emphasizes safe HTML preview—useful for inspecting what arrived without assuming every mobile quirk is reproduced. Use Quick Inbox when you need a quick receive + preview of a message you sent from a system you control.
Minimal valid mental model
A typical inline image welcome message:
multipart/relatedtext/htmlpart with<img src="cid:logo@mid">- Image part with
Content-ID: <logo@mid>andContent-Disposition: inline
If the Content-ID does not match, mobile clients show a broken image frame. If you only send remote https://cdn.../logo.png, clients with images blocked show empty boxes until the user taps “load.”
Intentionally broken fixture (failure demo)
On 2026-09-24, we inspected a crafted message (lab) where HTML referenced cid:hero@campaign but the MIME part used Content-ID: <hero@wrong>. Desktop webmail showed a broken icon; a mobile client hid the failure inside a blank header region—users thought the “email was empty” even though the OTP paragraph existed below the fold.
Limitation: visual QA on one desktop client misses mobile blank-header failures.
Working path
Same HTML with matching Content-IDs; OTP repeated in the first 200 characters of text; remote tracking pixel omitted. Mobile client with images blocked still showed the code.
Part table
| Raw part | Declared type | Observed rendering | Accessibility/security implication |
|---|---|---|---|
HTML cid: match | multipart/related + image | Inline logo shows when parts load | Decorative OK; not for OTP |
HTML cid: mismatch | related, wrong ID | Broken/blank | Users miss context; may phish-click “fix” links |
Remote https image | text/html only | Blocked until permission | Privacy win; layout collapse risk |
| Image-only OTP | image/png | Invisible if blocked | Critical failure — never do this |
| Plaintext alternative | text/plain | Always readable | Best fallback |
| SVG inline | varies | Often stripped | Treat as untrusted |
| Tracking pixel | 1×1 remote | May be proxied/blocked | Leak of open events |
MIME structure background: RFC 2387 (multipart/related), RFC 2045 (MIME).
Worked example for developers
Sending a staging welcome mail from Laravel/Node:
- Put the six-digit code in subject or first text line.
- Use inline CID only for branding.
- Provide
text/plainpart with the same code. - Receive in Mailby preview + one real mobile device with images off.
- Confirm code visibility before enabling fancy layout.
Related: Laravel welcome email delivery tests.
Security notes
- Remote images can phone home (open tracking). Mobile “protect mail activity” features exist for a reason.
- Do not instruct users to “always enable images” to complete signup.
- Lookalike emails often use perfect inline logos—domain checks still rule (lookalike domains guide).
When durable mailboxes matter
Rendering bugs are independent of temporary vs durable addresses. Use durable mail when the account matters; use temporary receive-only when you only need a disposable capture for a test message you generate.
Short answers
What causes inline image failures on mobile?
CID mismatches, image blocking, stripped CSS, or image-only content.
What should I do first?
Read the plaintext/HTML text with images disabled.
When is a permanent address safer?
Unrelated to images—use durable mail for durable accounts.
What evidence changes the recommendation?
If your client fully supports CID and users must see branding for trust—still keep codes in text.
Sources, test date, limitations
- Inspection date: 2026-09-24.
- Client behavior varies by OS version; re-test on target devices.
- Mailby preview ≠ every mobile engine.
- RFCs 2045/2387 linked above.
Building a deliberate fixture kit
Keep three .eml files in your repo’s tests/fixtures/mail/:
- good-cid.eml — matching Content-IDs, plaintext OTP
- bad-cid.eml — mismatched Content-IDs
- remote-only.eml — HTTPS images, no CID
Send each to a lab account and to a Mailby preview when testing your generator. Record screenshots on one iOS and one Android client with images disabled and enabled.
CSS and dark mode
Many mobile clients invert or filter images. Logos with transparent backgrounds vanish on dark themes. Prefer simple contrast, or accept that branding is secondary to text.
Avoid relying on background-image CSS for codes—frequently stripped.
Accessibility
Screen readers cannot read text burned into PNGs. If your compliance story mentions accessibility, image-only OTPs are already a defect.
Proxy and privacy features
Apple Mail Privacy Protection and similar features may prefetch images through proxies, breaking naïve open-tracking metrics and changing when remote images “load.” Design transactional mail to function without those metrics.
Remote image allowlisting
Enterprise MDMs sometimes block unknown image hosts. Host transactional images on a stable CDN aligned with your sending domain, or skip them.
QA script (15 minutes)
- Send good-cid to phone with images off → confirm OTP readable
- Send bad-cid → confirm plaintext still saves the user
- Send remote-only → confirm layout does not hide OTP above the fold
- Repeat on desktop webmail
- Note any client that downloads “related” parts aggressively on cellular
How this differs from the message-format hub
Hub explains MIME broadly. This article focuses on mobile inline images, with broken CID as the primary failure and a part-level table for accessibility/security implications.
Generator pseudocode checklist
When your app builds MIME:
- Create HTML with
cid:logo@msg - Attach image with matching Content-ID
- Set
Content-Disposition: inlinefor decorative parts - Add
text/plainwith the same human content - Avoid single-pixel trackers in transactional templates
- Integration-test by parsing MIME, not by eyeballing desktop Chrome alone
Receiving in Mailby preview
Safe preview is for inspection. Confirm whether images are blocked by default in the UI you use, and still ensure OTPs are textual. Product links: inbox, security.
Real-world bug story (composite)
A team shipped a welcome email where the subject was generic (“Welcome”) and the code existed only inside a hero PNG. Android users with data saver could not read it. Support volume spiked. Fix: subject Your code is 123456 plus plaintext part. Images stayed for brand.
Multipart tree (illustrated in text)
multipart/related
├─ multipart/alternative
│ ├─ text/plain
│ └─ text/html (img src=cid:logo@x)
└─ image/png (Content-ID: <logo@x>)
If alternative is missing, some clients behave oddly for users who prefer plaintext. Include it.
Tracking pixels vs transactional purity
Marketing platforms inject pixels by default. Transactional welcome/verify streams should use templates without them. Mixing streams causes privacy features to treat your OTP mail like a newsletter.
Internationalization
Languages with long code-related sentences can push OTPs below the fold under a large hero image. Put the code first in HTML order, not only visually first via CSS (CSS order may be ignored).
Testing on low bandwidth
Throttle the device network. Watch whether the client shows empty hero space for seconds. Users may navigate away. Text-first wins.
Pre-send acceptance criteria
A transactional mobile email is ready when:
- OTP or action instructions readable with images disabled
- Plaintext part present
- CID references match or remote images are non-critical
- Dark mode does not hide text contrast
- No essential data only in PNG/JPG
Meet these before debating hero aesthetics. Brand can follow utility—not the reverse. Validate with Quick Inbox preview plus one physical phone.
Client-by-client notes (high level)
Behaviors change by version, so re-verify quarterly:
- Some clients auto-download related parts on Wi-Fi only
- Some proxy remote images always
- Some strip SVG entirely
- Some rewrite links through scanners
Your fixture kit is the durable asset; screenshots go stale.
Design system rules for email images
- Max hero height guidance so OTP stays above the fold on small phones
- Approved CID naming convention (
cid:brand-logo@transactional) - Ban on image-only headers for transactional types
- Mandatory plaintext generation in the same PR as HTML changes
- Reviewer checklist item: “images disabled test done?”
Without design-system teeth, each campaign reinvents unsafe patterns. Engineers and marketers should share the fixture kit in tests/fixtures/mail/.
Compression and formats
Prefer compressed PNG/JPEG appropriately; avoid multi-megabyte heroes that stall cellular. Animated GIFs in transactional mail are usually a mistake. WebP support is uneven—test before relying.
Alt text
Always set meaningful alt on content images. Decorative images get empty alt. Alt text is not a place to hide OTPs either—some clients omit alt when images are blocked differently—keep codes in body text nodes.
Ship text that works on a cracked phone screen in sunlight with images off. Everything else is decoration. Rehearse that standard in design critiques until it feels boring—boring transactional mail is reliable transactional mail, and reliability is what signup and recovery flows optimize for.
Collaboration model
Marketers propose imagery; engineers own MIME validity; QA owns images-off passes. Three roles prevent a campaign manager from shipping an image-only OTP the night before launch. Write the RACI into the email design system so the argument happens once.
Final QA gate
No transactional template merges without an images-off screenshot on a mid-size Android phone and one iOS device. Store screenshots next to the fixture .eml files so regressions are visible in git history, not only in someone’s camera roll.
Remember: the user who never enables images is still a valid user. Design for them first, then layer branding that survives delay and dark mode without hiding the words they came to read.
Text first. Images second. Codes never only in pixels.
These closing lines exist to lock the operational habit into the document so skimming still leaves a usable rule.
Conclusion
Treat inline images as progressive enhancement. Build multipart fixtures on purpose, break them on purpose once, and ship codes in text. Preview safely in Quick Inbox when testing messages from apps you control, then confirm on a phone with images blocked.
For deliverability misfiles that hide even perfect MIME, see Outlook.com spam diagnosis.
Try it on Mailby
Open a receive-only disposable inbox when a short-lived address fits the job — session-bound, with timed purge.
