Email Header Analyzer

🩺 Diagnostics

Paste an email’s raw headers to trace its delivery path, timing and authentication results.

No sign-up required Runs on our own infrastructure Also available via API

Runs on our diagnostic API. We don’t attach your input to an account for these free tools; short-lived rate-limit/security logs may exist, and requests are rate-limited per IP.

Every email carries a stack of metadata that most people never see: dozens of lines above the message body that record where it came from, every server it passed through, how long each leg took, and whether the receiving side believed it was really sent by who it claims. When a message is delayed, lands in spam, or looks like a phishing attempt, the headers are where the answer lives. The lines added by the receiver’s own trusted servers are reliable — each relay stamps its own line as it accepts the message — but a sender can fabricate the lower Received lines that existed before the message reached that trusted infrastructure. So the hops from your trust boundary upward are the flight recorder; the ones below it are only as trustworthy as whoever wrote them. This tool parses that block for you, but it’s worth knowing how to read it yourself.

How to get the raw headers

The everyday “headers” view in your mail client (From, To, Subject, Date) is a tiny curated subset. You need the full raw source:

  • Gmail (web): open the message, click the menu at the top-right of the message → Show original. Copy the whole block, or use “Download Original.”
  • Outlook (desktop): open the message in its own window → File → Properties → Internet headers.
  • Outlook.com / new Outlook: open the message → ⋯ → View → View message source.
  • Apple Mail: select the message → View → Message → Raw Source (or ⌥⌘U).

Paste everything from the first Received: or Delivered-To: line down to the blank line before the body.

The Received chain reads bottom to top

The single most useful part of a header block is the sequence of Received: lines. Each server that touches the message prepends its own line to the top, so the chain is chronological from the bottom up: the oldest hop (closest to the sender) is at the bottom, the most recent hop (your own mail server) is at the top. Each line follows a rough grammar:

Received: from mail.sender.com (mail.sender.com [203.0.113.10]) by mx.receiver.com (Postfix) with ESMTPS id 4Xyz12 for <you@receiver.com>; Sat, 19 Jul 2026 14:02:11 +0000

Read it as: from the host that handed off the message (with the IP it actually connected from, in brackets — reliable for hops recorded by trusted infrastructure, because that server observed the connection directly; lower lines a sender added itself can be faked), by the server that received it, with the protocol used (ESMTP, ESMTPS for TLS), an id for tracing in that server’s logs, and a timestamp. To find the true origin of a message, walk to the bottom of the chain and read the first from IP that isn’t part of the sender’s own trusted infrastructure. That’s the IP you’d drop into a blacklist check or reverse DNS lookup.

Spotting delivery delays between hops

Because every hop is timestamped, you can measure exactly where a slow message got stuck. Subtract each hop’s time from the one above it (mind the +0000 timezone offsets — normalise to UTC first) and you get the dwell time at each relay. A message that took four hours to arrive usually didn’t crawl the whole way; it sat in one queue. Big gaps typically mean:

  • Greylisting — the receiver deferred the first attempt and the sender retried minutes later.
  • Queue backlog or rate limiting at a busy relay or ESP.
  • Content/AV scanning that quarantined the message briefly.

Clock skew is real, too: a relay with a wrong clock can make a hop look instantaneous or even negative. The tool lines the hops up and flags the largest gaps so you don’t have to do the arithmetic by hand.

Authentication-Results: SPF, DKIM and DMARC

The receiving server records its verdict in an Authentication-Results: header. This is where you confirm the message really came from where it claims:

Authentication-Results: mx.receiver.com; spf=pass (sender IP is authorized) smtp.mailfrom=sender.com; dkim=pass header.d=sender.com header.s=s1; dmarc=pass (p=reject) header.from=sender.com
  • spf=pass means the sending IP is authorised in the domain’s SPF record for the envelope sender (smtp.mailfrom).
  • dkim=pass means the cryptographic signature verified and the body wasn’t altered; note the signing domain (header.d).
  • dmarc=pass means SPF or DKIM passed and aligned with the visible From: domain — the check that actually stops spoofing. A dmarc=fail on a legitimate-looking message is a strong phishing signal. See the DMARC checker.

When mail is forwarded, you may also see ARC (arc=pass) headers, which preserve the original authentication results across a forwarder that would otherwise break SPF.

Other headers worth knowing

  • Return-Path vs. From. From: is what you see in the client; Return-Path: (the envelope sender / bounce address) is where failures go. A mismatch between them is normal for ESPs but is also a classic spoofing tell when the From is a brand and the Return-Path is a random domain.
  • Message-ID. A globally unique identifier assigned at send time, usually <random@sending-domain>. Useful for tracing a specific message in logs and for spotting forged ones (a Message-ID whose domain doesn’t match the sender is suspicious).
  • X-* headers. Non-standard, provider-specific extras — spam scores (X-Spam-Status), the originating client (X-Mailer), ESP campaign IDs. They’re optional and vary by provider, but often reveal what generated the message.

Nothing here is transmitted anywhere: the header block is parsed locally to serve your request and recipient addresses aren’t stored. If you’re debugging a broader deliverability problem rather than one message, pair this with the email health check and the authentication tools; the docs tie the pieces together.

Frequently asked questions

How do I read the Received chain — top or bottom first?
Bottom to top. Each server prepends its line, so the oldest hop is at the bottom and your server is at the top. The true origin is near the bottom of the chain.
How can I tell where a delay happened?
Every hop is timestamped. Convert the offsets to UTC and diff adjacent hops — the biggest gap is where it queued (greylisting, rate limiting, scanning). The tool flags this for you.
What tells me a message is spoofed?
A dmarc=fail in Authentication-Results, a From that doesn’t match the Return-Path or Message-ID domain, or a bottom-hop IP that isn’t the claimed sender’s. Confirm alignment with the DMARC checker.
Do you send or store anything when I paste headers?
No — headers are parsed in-memory to answer your request and recipient addresses aren’t stored. Nothing is sent or forwarded.