Mbox Archive Viewer
An mbox file is nothing but messages laid end to end, each one introduced by a line that begins with "From " and carries a sender and an asctime-style date. There is no length field and no terminator, so the only thing that marks the end of a message is a line any body is free to contain — and that, not MIME, is the hard part of reading one. Writers are supposed to escape such a line, but they disagree about how: mboxo escapes only a line that begins exactly with "From ", mboxrd escapes ">*From " as well so that ">From " unescapes back to "From ", and mboxcl and mboxcl2 escape nothing and instead write a Content-Length header that frames the body by length. This viewer works out which of the three the file in front of it appears to follow — a Content-Length on every message that lands exactly on the next separator, a ">>From " line that only an mboxrd writer produces — splits under that convention, and then tells you how many boundaries a reader following a different convention would have drawn somewhere else. That last number is the one worth reading, because it is how an archive silently loses mail: a message whose header block is empty is a "From " line that leaked out of somebody's body, and the archive has gained a message while the real one lost its tail. Per message you get the byte offset and length in the file, the From_ line's sender and date exactly as written, and the headers people actually look for — From, To, Cc, Subject, Date, Message-ID, In-Reply-To, References and Content-Type — with RFC 2047 encoded-words decoded, including the case where one multi-byte character is split across two adjacent encoded-words, which is where most viewers show mojibake. The MIME tree is listed part by part with its type, transfer encoding, filename (RFC 2231 continuations and all) and decoded size, and attachments are counted. Across the whole collection it reports the message count, total size, date range, the top senders, the thread structure derived from In-Reply-To and References, every Message-ID that appears more than once — the classic symptom of a merge gone wrong — and every message that carries none at all. It is not a mail client: an HTML part is shown as source rather than rendered, because rendering an archive you did not write means running its markup and fetching its remote images. It also does not extract attachments, verify DKIM or decrypt S/MIME. For reading a single message in depth, the EML viewer is the tool; this one is about the archive around it.
How to use
- Drop the .mbox file onto the box. Nothing is uploaded — the file is read in this tab, so a multi-gigabyte Takeout export is limited only by your machine.
- Read the convention line first. It says whether the file escapes bodies (mboxo/mboxrd) or frames them with Content-Length (mboxcl), and what evidence led there.
- Check the findings. Messages with no parsable header at all are unescaped "From " lines that split a real message in two, and the count of boundaries another convention would draw tells you how fragile the archive is.
- Scan the table for offsets and lengths. They are byte positions in the file you dropped, so you can cut a message out with dd or a hex editor and check it independently.
- Click a row number to open one message: its From_ line, the decoded headers, and the MIME tree with each part's encoding, filename and decoded size.
Frequently asked questions
- Why does my archive contain more messages than I ever received?
- Because a line in somebody's body began with "From " and the program that wrote the file did not escape it. There is no way for a reader to tell that line apart from a real separator: both are a line starting with "From " at the start of a line. The result is that one message is cut in two — the second half becomes a "message" with no headers at all, and the first half loses its tail. This tool flags exactly that case: a message whose header block is empty is almost never a real message. The fix has to happen at the writing end; mboxrd escaping or Content-Length framing both prevent it, plain mboxo mostly does not.
- What actually differs between mboxo, mboxrd, mboxcl and mboxcl2?
- Only how the end of a message is protected. mboxo prefixes ">" to a body line that begins exactly with "From " — which is lossy, because a reader cannot tell an escape from a genuinely quoted line. mboxrd prefixes ">" to any line matching ">*From ", so ">From " came from "From " and ">>From " came from ">From ", and the transformation is reversible. mboxcl leaves bodies untouched and adds a Content-Length header giving the body size in bytes; mboxcl2 is the same but stores the message in its original encoding with no escaping anywhere. Splitting is identical for mboxo and mboxrd — they differ only in what a reader must undo — which is why this tool reports a divergent split only for Content-Length files.
- Why is a message's length sometimes one byte shorter than I expect?
- The blank line between two messages belongs to neither of them. A reader that consumes it as part of the previous message ends up with a spurious trailing newline in every body, so the classic implementations drop it — but only when that blank line is a bare LF. A file written with CRLF endings has a blank line of two bytes, which the historical rule does not recognise, so it stays attached to the message before it. This tool reproduces that behaviour rather than silently improving on it, so its offsets and lengths line up with what the reference implementations report for the same file.
- Why does a Subject here look different from what I see in the raw file?
- Headers are ASCII-only, so anything else is wrapped as an RFC 2047 encoded-word, like =?UTF-8?B?SGVsbG8=?= or =?ISO-8859-1?Q?Caf=E9?=. This viewer decodes them, and it joins the bytes of adjacent encoded-words that share a charset before decoding. That second step matters more than it sounds: an encoder may split a multi-byte character across two words, and decoding each word on its own turns it into replacement characters. An unknown charset label — a typo, or a private x- name — is not fatal either; the payload is decoded as UTF-8 instead, which is exact for anything ASCII and only marks what it genuinely cannot read.
- Why is the HTML part shown as source instead of being rendered?
- Because an archive is untrusted input. Rendering an HTML body inside this page would run its markup and styles against the page around it, and any remote image, background or font it references would be fetched from wherever the sender chose to host it — which is how tracking pixels confirm an address and how a stored-XSS payload in a webmail archive finds a browser. Showing the source costs you the formatting and nothing else: the text, the links and the structure are all there, and a part's decoded size tells you whether the pretty version was worth anything.
- Duplicate Message-IDs and messages without one — how worried should I be?
- A Message-ID is supposed to be globally unique and assigned once, by the first system that handled the message. The same ID twice in one file usually means two copies of one message were merged in, from a backup and a live folder, or from two folders that both contained it; deduplicating on the ID is generally safe, though check the byte lengths first, because a message that passed through a list will differ in its trailer. A missing Message-ID is different: drafts, some automated senders and messages assembled by scripts never had one. They cannot be threaded and cannot be deduplicated, so a large count of them tells you how much of the archive is invisible to any tool that works by ID.
Related tools
EML File Viewer
Drop an `.eml` file and read the parsed message — key headers, plain-text and HTML body parts, and a list of attachments — all in the browser.
Java .properties Parser
Parse a .properties file exactly as java.util.Properties.load does — separators, escapes, continuations — and see every line that will surprise you.
vCard (.vcf) File Parser & Inspector
Drop or paste any vCard 2.1, 3.0 or 4.0 .vcf export and read every contact as a card — names, phones, emails, addresses, photos and custom X- fields.
ZIP Inspector
Drop a ZIP and see every file inside — sizes, contents, and per-file download — without unpacking it locally.
ELF Binary Inspector
Open a Linux executable, .so or .o in your browser: architecture, shared libraries it needs, build ID, and whether it is PIE, NX and RELRO hardened.
HAR File Inspector (HTTP Archive Viewer)
Drop a .har file from Chrome, Firefox or Safari DevTools and see every request — method, status, size, time — with slowest and largest tables.