Mail Header Analyzer — Manual
Full reference for the Mail Header Analyzer: all five tabs, findings, route and sending IP, Authentication-Results, spam filters, and the opt-in history.
Back to overview: Mail Header Analyzer · Open the live tool: www.jpkc.com/tools/mail-header/
This manual describes the Mail Header Analyzer in full: how the interface is laid out, what each of the five tabs shows, which findings the tool reports, how it breaks the headers down internally, and what limits pure browser operation brings. Labels appear here exactly as they do in the tool.
Interface layout
The tool is a single card with five tabs:
- Parse — the input view where you paste the headers and start the analysis.
- Overview — findings, a summary, and the key fields.
- Route — the delivery path as a timeline.
- Security — Authentication-Results, Received-SPF, DKIM signatures, ARC, and spam filters.
- All Headers — a searchable table of every header.
On start, only the Parse tab is active; the four analysis tabs are greyed out and unlock only once you've analyzed successfully. After the analysis, the tool jumps to the Overview tab and reports how many header fields it read ("… header fields analysed."). Clear disables the four tabs again and returns you to the input.
Workflow
The typical workflow has three steps:
- Get the headers — pull the raw headers from your mail client (see Getting the headers). The whole message works too; only the header section is read.
- Paste or upload — paste into the large text area, pick a file via Upload, or drop one in.
- Click Analyze (or press Ctrl+Enter or Cmd+Enter in the text area). The four analysis tabs fill up and you land in the Overview.
Parse tab
The Parse tab is mission control. A note at the top sums up the rules: paste the headers — or the whole message — and click Analyze; everything runs in the browser, nothing is uploaded. Below it sits a large, dark monospace text area (Raw Email Headers), with a button group in the card header:
- Recent — only appears once you've switched the history on and there are entries (see History: Remember, Recent and Forget).
- Upload — opens a file dialog for
.emland.txtfiles. The file is read locally, its header section copied into the text area (see File upload), and analyzed immediately. - Example — fills the field with a realistic sample header and analyzes it right away: a message that travelled from an internal application server through a Postfix gateway to Google, with ARC, Authentication-Results, Received-SPF, a DKIM signature, an encoded sender and subject, and SpamAssassin headers.
- Clear — empties the field, resets all views and the search field, and disables the analysis tabs.
Below the text area you'll find the Analyze button, the Remember analysed headers in this browser switch, and the Forget button. You can also drag a file straight onto the text area — it highlights while you hover, and the file is read and analyzed when you drop it.
At the very bottom, a help card (How to get email headers) explains where to find them — see Getting the headers.
If you paste nothing and click Analyze, a notice reminds you ("Please paste email headers first."). If not a single header field can be read from the text, you get "No header fields found — expected lines like "Name: value"."
History: Remember, Recent and Forget
The history is opt-in and off by default. Only once you turn on Remember analysed headers in this browser does the tool store each analyzed message in your browser's localStorage — and only the header section, never a body you may have pasted along with it. It keeps at most ten entries; a message you analyze again moves to the top instead of appearing twice.
You reach the entries through the Recent dropdown. Each entry is labelled with the decoded subject (or, failing that, the first line), cut to 70 characters; a click loads the headers into the text area and analyzes them again.
- Forget deletes all remembered headers ("Remembered headers deleted.").
- Switching it off deletes the history immediately as well.
- Entries left over from before you opted in are removed when the page loads — only what you explicitly chose to remember stays.
Overview tab
The overview consists of three cards.
Findings — what the analysis turned up, sorted by severity: red errors, orange warnings, purple notes. This is where missing required fields, suspicious sender constellations, failed authentication, date inconsistencies, and clock skew end up. If there's nothing to report, a green check mark says: "Nothing conspicuous in the header — no proof of a genuine message, only no known warning signs." Every rule is listed under Findings in detail.
Summary — the key facts as a list:
- Sender — display name and address from
From(decoded). - Sending server — the detected sending IP with its classification (e.g.
Public (globally routable)orDocumentation (TEST-NET-2)), the host name from theReceivedline, and a copy icon. How the tool picks it is explained under Received lines, TLS and sending IP. - Client IP — the value from
X-Originating-IP, if present. - Authentication — badges for SPF, DKIM, DMARC, and ARC from the topmost
Authentication-Resultsfield, followed by "by" and the name of the checking server. - Spam filters — the verdicts of the detected spam filters as badges (
spam,ham,bulk,trusted). - Delivery — the number of hops and, once there are at least two hops and the first and last carry a timestamp, the total transit time ("in transit").
Key fields — a table of the central headers, wherever they occur: From, Sender, Reply-To, To, Cc, Subject, Date, Message-ID, Return-Path, List-Id, List-Unsubscribe, Precedence, X-Mailer, User-Agent, MIME-Version, and Content-Type. Values appear decoded (see Encoded words), each with a copy icon. If a field occurs more than once, the table shows every occurrence. An extra row, Date (local), converts the Date field to your local time and shows the original offset (UTC+01:00).
Route tab
The Route tab reconstructs the delivery path from the Received fields. Each mail server adds its line at the top (newest first); the tool flips the order so the timeline runs from the first hop (green) to the last hop (blue). Intermediate stops are numbered in grey. A note above the timeline reminds you that only the topmost Received fields come from your own provider — the sender can forge the lower ones.
If the message has a valid Date field, the timeline opens with a Written marker: the moment the message was written, according to the sender.
Per hop, a card shows:
- from and by — the delivering and the accepting server.
- the IP address of the delivering server with a badge: grey
internalfor private, loopback, link-local, CGN, and reserved addresses, otherwise blue with the classification from the library of the IP tools. - Protocol — the content of the
withclause, e.g.ESMTP,ESMTPS, orSMTP. - TLS status — a green lock with the TLS version (e.g.
TLS 1.3) or simplyTLSwhen the line shows evidence of encryption. If there's no such evidence on a hop that has afromclause and whose IP isn't recognised as internal (or that names no IP at all), an orange "no TLS recorded" appears. Internal hops (such aslocalhost) and lines withoutfromget no warning. - for and id — recipient address and queue ID, if the server recorded them.
- Timestamp — when this server accepted the message, converted to your local time zone. Next to it sits the original offset the server logged (e.g.
UTC+01:00orUTC-08:00).
Between two hops the tool shows the waiting time as a gap: "waited 1m 52s at mail-gw.example.com". A timestamp always marks when a server accepted the message — so the difference is the wait at the previous server (queue, greylisting), not the duration of a single hop. Gaps are colored by duration: under 10 seconds green, under 1 minute purple, under 5 minutes orange, 5 minutes and up red. If a difference is negative, the servers' clocks disagree; the tool then reports a Clock skew ("the real waiting time is unknown") instead of an invented waiting time.
Durations are rounded down, never up, and show two units at most: a wait of 1 hour, 59 minutes and 59 seconds appears as 1h 59m, anything under a second as <1s, and from one day on as 1d 2h.
If there are at least two hops and the first and last carry a timestamp, a box at the end sums up the total transit time ("Total transit") with the number of hops. If at least one wait is positive, it also names the longest wait ("Longest wait") and the server where it happened. If there are no Received fields, you see "No Received fields found." instead.
Security tab
A note at the top makes it clear: the tool shows the results the receiving servers recorded — it does not re-check signatures and does not query DNS. And only the topmost Authentication-Results field comes from your provider. Below that follow up to five sections:
Authentication-Results — one card for each such field, titled with the name of the checking server (the authserv-id, e.g. mx.google.com). A badge classifies the card: green "topmost — from your provider" for the top field, orange "added on the way — can be forged" for all others. The table lists every check with Method (spf, dkim, dmarc, arc, and any other method the server recorded), Result as a colored badge (pass green, fail/permerror red, softfail/temperror/policy orange, neutral/bestguesspass purple, none grey), and Details — properties such as smtp.mailfrom=, header.from=, header.i=, or header.s=, plus a reason. If a field contains no checks, it reads "No results (none).". If the field is missing altogether, a notice explains that the receiving server recorded no SPF, DKIM, or DMARC checks.
Received-SPF — if present, a table with Result, Client IP, Envelope from, and the checking server's comment.
DKIM signatures — one row per DKIM-Signature: Domain (d=), Selector (s=), Algorithm, Matches From (whether the signing domain belongs to the same organization as the From domain: green yes, orange no), and Signed fields. The card header reminds you that only the receiver verifies the signature itself — the outcome is in the Authentication-Results.
ARC chain — if there are ARC-Seal fields: their count, the highest instance i=, the chain validation result cv=, and the sealing domain. ARC lets forwarders and mailing lists vouch for the authentication results they saw.
Spam filters — a table with Filter, Field, Value, and Verdict for every detected spam header (see Spam headers). If the tool finds none, it reads "No SpamAssassin, Rspamd or Microsoft spam fields found.".
On a phone, the tables in this tab are stacked: each row turns into a block of labelled values instead of scrolling sideways.
All Headers tab
Here you see every parsed header in the order it appeared in the message — numbered, with header name and value, each value with a copy icon. Above the table:
- a search field (
Search headers...) that filters the table live (matches in number, name, or value; case-insensitive); - the Show raw values (encoded words not decoded) switch — shows values as they appear in the message, i.e. with
=?UTF-8?B?…?=instead of decoded text; your search stays in place; - Copy All — puts the header section on the clipboard as text;
- Download — saves the header section as a text file named
email-headers.txt.
A line below the table states the number of header fields and whether the values are shown decoded ("encoded words decoded") or raw ("raw"). This tab, too, shows duplicates in full, such as every Received line.
Getting the headers
The help card in the Parse tab summarizes how to obtain the raw headers:
- Gmail — open the message → More (three-dot menu) → Show original → copy the headers.
- Outlook — open the message → File → Properties → copy from Internet Headers.
- Thunderbird — open the message → Ctrl+U → copy the headers (above the blank line).
All that matters is the header section — everything up to the first blank line. If you copy the whole message including the body, the tool cuts the body off itself and mentions it as a note in the findings.
How parsing works
The evaluation follows the relevant standards: RFC 5322 for headers and dates, RFC 2047 for encoded words, RFC 5321 for Received lines, and RFC 8601 for Authentication-Results.
Header format and unfolding
The header section ends at the first blank line (including one that contains only spaces or tabs); everything after it is body and is ignored. Before that, the tool normalizes line endings (\r\n → \n) and removes a byte order mark as well as an mbox separator line starting with From (no colon).
It then splits the section into Name: value pairs. A field name may consist of any printable ASCII character except the colon — so names like X_Custom are recognized too. Lines starting with a space or tab are continuations of the previous header and are reattached to it (unfolding) — so long, wrapped headers such as Received or DKIM-Signature stay intact as a unit. Lines that are neither a header nor a continuation are ignored and reported as a finding with their first line numbers. Order and duplicates are preserved — important, because Received occurs multiple times.
Encoded words (RFC 2047)
Subjects, display names, and other fields with accented characters or non-Latin scripts appear in the message as encoded words, such as =?UTF-8?B?…?= (Base64) or =?UTF-8?Q?J=C3=B6rg?= (Quoted-Printable). The tool decodes both variants using the character set the word declares. Whitespace between two directly adjacent encoded words is dropped, as the standard requires; consecutive words in the same character set are joined before decoding, so UTF-8 characters split across the word boundary don't break. The switch in the All Headers tab shows the raw form.
Dates and time zones
Date and the timestamps of the Received lines go through a dedicated RFC 5322 parser. It understands comments, two-digit years (below 50 → 20xx, otherwise 19xx), numeric offsets, and the legacy zone names UT, GMT, Z, UTC, EST, EDT, CST, CDT, MST, MDT, PST, and PDT. The offset -0000 and unknown zone names count as "time zone unknown"; the tool then reads the time as UTC. For the Date field it reports this as a note in the findings, along with a weekday that doesn't match the date; for the Received timestamps neither is reported.
Received lines, TLS and sending IP
Each Received line is split into its clauses from, by, via, with, id, and for; whatever follows the last semicolon is the timestamp. Comments in parentheses belong to the clause before them — so a from inside a comment isn't mistaken for the sender. The IP address comes from an address literal such as [198.51.100.42] or [IPv6:…], or from the comment after from.
A hop counts as encrypted if its with clause reads ESMTPS, ESMTPSA, UTF8SMTPS, UTF8SMTPSA, LMTPS, or LMTPSA, or if the line contains hints such as TLS, SSL, version=TLS…, cipher=, or HTTPS. The tool reads the version from version=TLS1_3 or TLSv1.2.
The sending IP is the IP of the oldest hop that is not internal — the tool skips private networks, loopback, link-local, carrier-grade NAT, and reserved ranges, because they're never the actual sending server. Addresses from documentation networks do count (they show up in examples) but are labelled as such.
Authentication-Results, DKIM and ARC
Each Authentication-Results field is evaluated on its own: the name of the checking server, every check with its result, properties, and reason. Only the topmost field is trustworthy — your provider's server wrote it. Fields further down were added by someone along the way, possibly the sender; a forged dkim=pass down there therefore can't fool the tool. Only the topmost field feeds the badges in the overview and the findings.
The tool reads DKIM-Signature and ARC-Seal fields as tag lists (d=, s=, a=, h=, i=, cv=). Whether a domain "matches" is decided by comparing the organizational domain: the last two labels, or the last three for endings such as co.uk or com.au. That's deliberately rough — DMARC itself uses the Public Suffix List — but good enough for hints.
Spam headers
Three filter families are recognized:
- SpamAssassin —
X-Spam-Status(status with score and threshold, verdictspam/hamfromYes/No, plus the list of tests),X-Spam-Score, andX-Spam-Flag. - Rspamd —
X-Spamd-Result(score / threshold,spamonce the threshold is reached),X-Rspamd-Score, andX-Rspamd-Action(no action=ham, any other action =spam). - Microsoft — the SCL (spam confidence level) from
X-MS-Exchange-Organization-SCLorX-Forefront-Antispam-Report(5 and upspam, −1trusted), the filter verdict SFV (SPM=spam), the connecting IP (CIP), and the BCL value for bulk mail fromX-Microsoft-Antispam(7 and upbulk).
Other spam headers, such as X-Spam-Level, aren't evaluated; you'll find them in the All Headers tab.
File upload
Upload and drag-and-drop accept .eml and .txt files up to 25 MB. The tool reads the file locally as text, copies only the header section into the text area, and reports "Read the header section of …" — with "(body left out)" added when it cut off a body. The analysis then starts automatically. If the file contains no header section, you get "No header section found in the file.".
Outlook .msg files are a binary format and are rejected; the error message explains the way out: open the message in Outlook and copy the Internet headers via File → Properties. Any other extension gets "Please choose a .eml or .txt file.".
Findings in detail
The Findings card in the Overview tab collects everything that stands out in a header. A finding is a hint, not a verdict: some are triggered by legitimate mail too, and a message without findings isn't automatically genuine.
Errors (red)
- No
Fromfield (required by RFC 5322). - SPF, DKIM, DMARC, or ARC with
failorpermerroraccording to the topmostAuthentication-Results.
Warnings (orange)
- Lines that are neither a header nor a continuation (with line numbers).
- No
Datefield; noMessage-ID— legitimate servers almost always set one. From,Date,Subject,Message-ID,Sender,Reply-To, orTooccurs more than once — mail clients may then show different values.Dateis not a valid RFC 5322 date, or lies more than 15 minutes after the last delivery (if there are noReceivedfields or the last hop has no readable timestamp: after the current time).- The display name contains an email address that isn't the actual sender address — a classic phishing trick.
Reply-Topoints to a different domain than the sender.- There are DKIM signatures, but none from the sender's domain.
- SPF, DKIM, DMARC, or ARC with
softfailortemperror.
Notes (purple)
- The text contained a body; only the header section was analyzed.
- A
Bccfield is present (normally removed before delivery). - The weekday in the
Datefield doesn't match the date; theDatefield has no usable time zone. - The first server accepted the message more than 24 hours after its
Date. Return-Pathbelongs to a different domain thanFrom— normal for newsletters and mail services; DMARC then passes only via a matching DKIM signature.- The receiving server recorded no DMARC result; there are several
Authentication-Resultsfields; or there is none at all (reported only whenReceivedfields are present). - A hop logged its time more than a minute before the previous one (clock skew).
Operating limits and privacy
- Fully client-side: parsing, route computation, authentication and spam evaluation, and file reading all run only in the browser. There is no backend, no API, no upload endpoint — your headers never leave the machine.
- History only on request: without the Remember analysed headers in this browser switch, the tool stores nothing. Switched on, it keeps up to ten header sections in
localStorage; Forget or switching it off deletes them (see History). - Header values are treated as hostile: headers come from foreign, often malicious messages. The tool outputs every value as text only, never as HTML — a crafted subject or sender can't run code in the tool.
- Standards-based parsing with limits: the parsing follows the RFCs, but mail servers write
Receivedlines quite freely. Unusual formats may be recognized incompletely — the All Headers tab still shows the raw value. Domain matching uses a rough organizational domain instead of the Public Suffix List. - No live DNS check: the tool only reads what the headers say. It does not query DNS records and does not cryptographically verify a DKIM signature — it shows the results the receiving mail servers already noted in
Authentication-Results.
For the introduction and target audiences see the overview page. Concrete walkthroughs are in the examples, strategy and pitfalls in the tips & tricks. You can try everything directly in the tool.