EML Email Viewer
View and parse EML email file contents.
Overview
A .eml file is a message saved in the format it travelled in: headers, a blank
line, then the body. Mail clients hide most of it, which is fine until you need
to know what the message actually contained — a header your client does not
display, a subject that arrived as mojibake, or the structure of a message that
renders wrongly.
This viewer splits the file at the header boundary, unfolds the headers, decodes the MIME encoded-words in their declared character set, and shows you both the key fields and the raw body.
How to use
- Save the message as
.eml, or copy its raw source. In Thunderbird, drag the message to your desktop; in Apple Mail, View → Message → Raw Source; in Outlook, Save As → Outlook Message Format then export, or use File → Save As → Text. - Paste the contents. Headers first, then a blank line, then the body — that is the whole format.
- Read the summary fields, then scan the raw body for structure.
Encoded-words and why subjects arrive broken
Headers are ASCII-only by specification. Non-ASCII text is carried as an
encoded-word: =?charset?encoding?data?=, where the encoding is B for
base64 or Q for a quoted-printable variant.
The character set in the middle matters, and it is where most tools go wrong.
Japanese subjects are still routinely sent as ISO-2022-JP — an escape-sequence
encoding that predates Unicode and remains the default in several mail clients.
Western European mail still uses ISO-8859-1 and windows-1252. A decoder that
assumes UTF-8 turns all of those into mojibake, and the result looks like a
corrupt file rather than a decoding mistake.
This viewer reads the declared charset and decodes accordingly, so
=?ISO-2022-JP?B?…?= becomes readable Japanese and =?windows-1252?Q?it=92s?=
becomes it's with the correct typographic apostrophe. An unknown or
misspelled charset falls back to UTF-8 rather than failing.
Header folding
Long headers are split across lines, with continuation lines beginning with
whitespace. A Received header or a To list with twenty addresses will span
many lines in the file, and the wrapping is not meaningful — it is a transport
rule, not part of the value.
Headers are unfolded before parsing, so a folded value is read as one string.
This is worth knowing when you are reading the raw text yourself: a grep for a
header value will miss anything that happened to wrap.
What the body shows
The body is shown exactly as it appears in the file, and that is deliberate.
Most real messages are multipart/alternative (a plain-text version and an HTML
version of the same content) or multipart/mixed (content plus attachments).
Each part has its own Content-Type, its own charset and its own
Content-Transfer-Encoding, and the parts are separated by a boundary string
declared in the top-level headers.
Showing one decoded part as though it were “the message” hides that structure, and the structure is usually what you came to see: which part a client is rendering, whether the plain-text alternative matches the HTML, whether an attachment is where you expect. So the raw body stays raw.
That does mean quoted-printable bodies show =3D for = and soft line breaks
as trailing =, and base64 parts show as base64. If you need one of those
decoded, copy the part and use Base64 decode or
URL / percent decode on it.
Headers your client does not show you
The summary lists the seven fields you normally want. The raw text you pasted contains the rest, and several of them answer questions clients hide.
Return-Pathis the envelope sender — where bounces go. It is set by the sending server and is frequently different from theFrom:header, which is the address a human sees. When SPF passes but DMARC fails, this mismatch is usually why.List-UnsubscribeandList-Unsubscribe-Postare what makes a one-click unsubscribe button appear in Gmail. Bulk mail without them gets marked as spam more often.Auto-Submittedmarks machine-generated mail. Absent on an automated message, it will trigger out-of-office replies and mail loops.In-Reply-ToandReferencesare how clients build a thread. A reply that appears as a new conversation is missing one of them.Content-LanguageandAccept-Languageexplain why a multi-language sender picked the version it did.X-*headers are whatever the sending infrastructure added. Spam scores, campaign ids and internal queue names all show up here, and they are the quickest way to identify which system actually sent a message.
Examples
- A subject that arrives as gibberish. Paste the message here. If the subject is readable, the sender is fine and the receiving client is mishandling the charset.
- “The message renders differently in Outlook.” Look at the boundary
structure. A
multipart/alternativewhere the two parts disagree explains most of these reports. - A missing header. Clients display a curated subset.
List-Unsubscribe,Auto-Submitted,X-Failed-Recipientsand similar are in the file even when nothing shows them. - Confirming what you actually sent. Save a message from your own Sent folder and read it back. Encoding surprises are much easier to see in the raw form.
Notes
The header/body split is the first blank line, per the format. A file with no blank line at all is treated as headers only, which is what you want when someone pastes just the header block.
Nothing here validates the message. A .eml with a malformed Date, a missing
Message-ID or a boundary that never appears in the body will display exactly
as it is, because the point is to see what the file contains rather than what it
should have contained.
For the delivery path, per-hop delays and the SPF, DKIM and DMARC verdicts, use the email header analyzer. It reads the same headers with a different question in mind.