About this tool
Email headers answer three questions people ask all the time: why did this message take two hours to arrive, is this really from my bank, and why did it land in spam? Reading them by hand is slow — a dozen Received lines in reverse order, timestamps in different time zones, and an Authentication-Results header full of abbreviations. This email header analyzer parses the headers in your browser and lays them out: the route the message took, the delay at each hop, what the receiving server concluded about SPF, DKIM and DMARC, and whether the DKIM signature still verifies today. Nothing is uploaded. The only network request the page ever makes is the DKIM public-key lookup, and only after you press Verify DKIM: the name selector._domainkey.domain is sent to a public DNS-over-HTTPS service (Cloudflare, with Google as fallback), which sees your IP address as any DNS query does. The message, its recipients and the headers themselves are never sent anywhere.
Trace the route and find the delay
Every Received header is one hop. The page lists them oldest first and splits each into the claimed sending host, the reverse-lookup name and IP in brackets, the receiving host, the protocol (SMTP, ESMTPS, ESMTPSA, LMTP…) and the time. The protocol letters are decoded per RFC 3848 — an S means the connection used TLS, an A means the sender authenticated — so you can see whether the message was encrypted in transit. The delay of a hop is its timestamp minus the previous one, drawn as horizontal bars with the longest hop in red, which is usually where a delayed message spent its time. A negative delay is labelled clock skew rather than treated as an error, because mail servers' clocks disagree; a hop with no usable time is labelled cannot compute and does not break the chain. Private addresses (RFC 1918, 127.*, ::1) are marked internal. IP addresses are shown as text only — there is no geolocation lookup, which would mean sending them to a third-party API.
Read Authentication-Results with the right amount of trust
Authentication-Results (RFC 8601) is where a receiving server writes down what it decided: spf=pass, dkim=fail, dmarc=none, plus arc, iprev and bimi where present. The page splits each header into its authserv-id and methods, and gives every result a plain-language sentence — what softfail, temperror, permerror and neutral actually mean and what commonly causes them. One warning sits above the whole list: anyone along the path, including the sender, can add an Authentication-Results header. Only the line written by your own receiving server is trustworthy; lines from intermediate hops, or from the sender itself, prove nothing. ARC headers (RFC 8617) are grouped by instance and shown for reference, but this version does not verify ARC seals.
Verify DKIM in the browser, with today's key
The headline feature is a real DKIM verification (RFC 6376) rather than a readout of someone else's verdict. For each DKIM-Signature the page parses the tags, fetches the public key named by s= and d=, canonicalises the signed headers as c= says, and checks the signature with WebCrypto. Headers listed in h= but missing from the message count as empty strings, exactly as the standard requires, so a header added after signing cannot pass. rsa-sha256 is verified with RSASSA-PKCS1-v1_5; ed25519-sha256 (RFC 8463) is verified when the browser's WebCrypto supports Ed25519 and reported as cannot verify — not as a failure — when it does not; rsa-sha1 is verified but flagged as deprecated by RFC 8301, and RSA keys shorter than 1024 bits are rejected as that RFC demands. The verdict is pass, fail with a reason (key not found, key revoked when p= is empty, expired x=, signature mismatch, body hash mismatch, key too short), cannot verify (DNS error, unsupported algorithm, no body) or malformed. A signature with l= gets a warning that only the first N bytes of the body are covered and anything appended afterwards is unsigned. Remember that the key you fetch is the key published now: if the sender has rotated keys since the message was sent, an old message fails verification without being forged.
Headers only, .eml, or .msg
A full .eml file is the only input that lets the body hash bh= be checked, because the raw bytes of the body are needed. If you paste headers only, the page still verifies the header signature — which covers the bh= value — and reports that the headers are intact but the body could not be checked. Every .msg file is in this situation: a received message's .msg keeps the transport headers as a property but not the original MIME body (and a .msg saved before sending has no transport headers at all), so a .msg is always a headers-only verification. From the EML viewer and the MSG viewer, a one-click link hands the message to this page through session storage, never through the URL. The summary card shows the three sender identities side by side — the From domain, the Return-Path domain and the DKIM d= domain — with DMARC alignment judged on the organisational domain (relaxed mode, RFC 7489), and offers to check the From domain's SPF, DKIM and DMARC records on the email DNS check page; only that domain, which is public, goes into the link.
What this page does not claim
It never says a message is safe or genuine — it says which checks passed and which failed, and a passing DKIM signature only proves that the d= domain signed the message, not that the domain belongs to who you think. SPF is not re-checked: SPF depends on the IP that delivered the message and the DNS of that moment, so re-running it later tells you nothing; the page shows what the receiving server recorded instead. DKIM failures on forwarded messages, mailing-list messages and messages rewritten by a corporate mail gateway are common and expected, and the failure text says so. Spam-filter headers such as X-Spam-Status or X-Microsoft-Antispam are shown verbatim without interpretation, because their formats are not public. The Markdown report and the JSON export mask recipient addresses by default so you can share them.