Skip to content

Email Header Analyzer

Email headers record every server a message passed through, in reverse order, with a timestamp at each hop. This analyzer rebuilds that chain forwards, calculates the delay each server added, and extracts the SPF, DKIM and DMARC verdicts the receiving mail server stamped on the message.

Gmail: ⋮ → Show original. Outlook: File → Properties → Internet headers. Apple Mail: View → Message → All Headers. Paste everything down to the first blank line.

Headers are parsed on our server and never stored.

Why Received headers read backwards

Every MTA that handles a message *prepends* its own Received: header to the top of the block, per RFC 5321 §4.4. Nothing rewrites what came before. That gives you a tamper-evident log where the topmost Received header is the last server to touch the message — usually the recipient's own mailbox provider — and the bottommost is the first, closest to the sender. This tool reverses them so hop 1 is where the message started and the last hop is where it landed.

The practical consequence: only the headers added *above* the point you trust are trustworthy. A spammer can forge as many Received headers as they like in the message they hand to your MX. Start reading from the top, and stop trusting the chain the moment you reach a host that is not yours and not your provider's.

Received: from mail.example.com (mail.example.com [93.184.216.34])
        by mx.recipient.net with ESMTPS id 4c9d2f
        for <[email protected]>;
        Mon, 01 Sep 2026 10:00:10 -0700 (PDT)
         │        │                    │
         │        │                    └── timestamp: everything after the last ';'
         │        └── the receiving host, and the protocol it accepted
         └── the sending host as it announced itself, plus the IP the receiver actually saw
One Received header, annotated
The hostname before the parentheses is what the sender claimed in its HELO/EHLO. The address in square brackets is the TCP peer the receiver observed. When those disagree, the bracketed IP is the fact and the claimed name is an assertion — check it with a reverse DNS lookup.

Reading the delays

The per-hop delay is the difference between one hop's timestamp and the previous one's. Most hops complete in under a second. A delay that stands out tells you where to look:

Read the full explanation of email header analyzer results ↓
DelayUsual causeWhat to do
0–2 sNormal handoffNothing.
5–60 sContent scanning, DNS timeouts on the receiver, a slow blocklist lookupCheck whether the sending IP is on a blocklist — RBL timeouts are a classic cause.
1–15 minGreylisting, or a queue retry after a 4xx deferralExpected on first contact between two hosts. Repeated occurrences mean the greylist entry is not being remembered.
HoursSustained deferral — full queue, rate limiting, or repeated connection failuresLook at the sending server's own logs; the header only shows when it finally succeeded.
NegativeClock skew on one of the relaysDelays either side of that hop are unreliable. Fix NTP on the offending host.

A large delay on the *first* hop is different in kind: it means the message sat in your own outbound queue. That points at your sending infrastructure, not the recipient. Confirm your MX and outbound host are reachable with the SMTP connection test.

The authentication verdicts

The receiving server records its own conclusions in an Authentication-Results: header. This is the single most useful line in the whole block, because it is the receiver telling you exactly what it decided:

Authentication-Results: mx.google.com;
       spf=pass smtp.mailfrom=example.com;
       dkim=pass header.d=example.com;
       dmarc=pass header.from=example.com
  • spf=pass — the connecting IP is authorised by the SPF record of the MAIL FROM (envelope sender) domain. Note that this is the Return-Path domain, not the visible From:.
  • spf=softfail — the IP is not authorised, but the policy ends in ~all so the receiver accepted it anyway. Treat this as a failure you have not fixed yet.
  • spf=none — the domain publishes no SPF record at all. Fix it with the SPF checker.
  • spf=permerror — the record is syntactically broken or exceeds the ten-DNS-lookup limit. This fails DMARC as surely as a hard fail does.
  • dkim=pass with header.d= — a signature verified, and the header tells you which domain signed. If header.d is your ESP's domain rather than yours, DKIM alignment for DMARC will fail even though DKIM itself passed.
  • dmarc=pass — at least one of SPF or DKIM passed *and* aligned with the visible From: domain. DMARC needs alignment, not just a pass.

Older or simpler receivers may stamp only a Received-SPF: header instead. The analyzer falls back to it when Authentication-Results is absent. If neither header is present, the receiver either does not perform authentication checks or you pasted an incomplete block — the verdict is reported as "not stamped" rather than guessed.

Authentication-Results headers are only trustworthy when added by the server that delivered to your mailbox. Anyone can insert a fake one further upstream. Check that the host named at the start of the header is your own mail provider.

The alignment trap

The most common confusing result is spf=pass combined with dmarc=fail. That happens when the Return-Path domain and the From: domain differ — typical when a marketing platform sends on your behalf using its own bounce domain. SPF validates the bounce domain and passes; DMARC then checks alignment against the From: domain, finds a mismatch, and falls back to DKIM. If DKIM also signs with the platform's domain rather than yours, DMARC fails despite two green checks.

The fix is to have the platform sign with a d= value under your own domain (every serious ESP supports this) or to use a custom Return-Path subdomain that you delegate to them. The analyzer flags a From/Return-Path domain mismatch for exactly this reason. Verify the resulting policy with the DMARC checker.

Getting the raw headers out of your mail client

  • Gmail — open the message, click the ⋮ menu, choose *Show original*. Copy from the top of the block down to the first blank line.
  • Outlook (desktop) — *File → Properties*, then copy the *Internet headers* box.
  • Outlook on the web — ⋯ menu → *View* → *View message details*.
  • Apple Mail — *View → Message → All Headers*, or ⌘⇧H.
  • Thunderbird — *View → Headers → All*, or Ctrl+U for the full source.
  • Command line — for a Maildir file, everything before the first empty line is the header block.

Paste the whole block, including folded continuation lines — the ones indented with a space or tab. The analyzer unfolds them per RFC 5322, so a Received header split across four lines is parsed as one hop rather than four fragments.

Doing the same checks from the command line

Once the headers tell you which IP and which domains are involved, verify the claims independently rather than trusting the header text:

# Does the connecting IP really have the reverse DNS the header claims?
dig +short -x 93.184.216.34

# ...and does that name resolve forward to the same IP? (forward-confirmed rDNS)
dig +short mail.example.com A

# Read the SPF record the receiver evaluated
dig +short example.com TXT | grep spf1

# Fetch the DKIM key named by the s= and d= tags of the DKIM-Signature header
dig +short google._domainkey.example.com TXT

# Read the DMARC policy that decided the outcome
dig +short _dmarc.example.com TXT
Verify what the headers assert

A sending host whose reverse DNS does not forward-confirm is one of the strongest spam signals there is, and it is invisible in the Authentication-Results line. If you are diagnosing your own outbound mail, fix that before anything else — then run the full deliverability test to see SPF, DKIM, DMARC, MX and PTR together.

Frequently asked questions

Which Received header is the real sender?
The bottom one — but only if you trust everything above it. Read from the top down: each header was added by a server you can identify, until you reach one you cannot. Headers below that point were supplied by the sender and can be entirely fabricated. For a message delivered to you directly, the lowest header added by your own provider names the true connecting IP in square brackets.
Why does the total transit time look wrong?
Timestamps come from each server's own clock, and mail relays are not always in sync. A hop with a clock a few minutes fast produces a negative delay on the next hop and inflates the one before it. The analyzer flags negative delays for this reason. Treat the total as approximate whenever one appears.
What does spf=pass but dmarc=fail mean?
SPF passed for the envelope sender (Return-Path) domain, but that domain does not align with the From: domain the recipient sees, and DKIM did not save it either. This is the standard failure mode for mail sent through a third-party platform using its own bounce domain. Have the platform sign DKIM with d= under your domain, or delegate a Return-Path subdomain to them.
Are the headers I paste stored anywhere?
No. The header block is posted to our server, parsed in memory, and the result is returned in the same response. Nothing is written to disk or logged. That said, headers contain recipient addresses and internal hostnames, so redact anything sensitive before pasting into any online tool, including this one.
Why is there no Authentication-Results header at all?
Either the receiving server does not perform authentication checks — common on small self-hosted setups — or you pasted only part of the header block. Some clients show an abbreviated view by default; make sure you used "Show original" or the equivalent rather than copying what is displayed above the message body.
A hop took several minutes. Is that a problem?
Usually not, on its own. Greylisting deliberately defers the first delivery attempt between two hosts, so a 5–15 minute gap on first contact is normal and self-correcting. It becomes a problem when it happens on every message, which means the receiver is not recording the greylist triplet, or when the delay is in your own outbound queue rather than at the receiver.
What is the X-Forefront-Antispam-Report or X-Spam-Status header?
Those are vendor-specific scoring headers — Microsoft and SpamAssassin respectively. They are not standardised and this tool does not interpret them, because their meaning changes between versions and deployments. When you have one, read it against that vendor's current documentation; the SCL and BCL values in the Microsoft header in particular are worth understanding if you send to Office 365 tenants.
Can I use this to prove a message was forged?
It gives you the evidence, not the conclusion. A forged message typically shows a connecting IP that does not match the claimed sending domain's SPF record, no valid DKIM signature for the From: domain, and often invented Received headers below the first trustworthy one. Verify each claim independently with dig rather than relying on what the headers assert about themselves.