How to Read Email Headers: A Complete Analysis Guide
Learn how to read email headers step by step: the Received chain, Authentication-Results, ARC, X- headers, and how to trace an email's true origin IP.
01Inspect
Capture the production-like input.
02Decide
Validate the protocol or event evidence.
03Verify
Automate the repeatable check.
Email headers are the hidden metadata block at the top of every message, recording each server hop, every authentication verdict, and the true originating IP. Learning how to read email headers is the single most useful deliverability debugging skill: open the raw source of any email that landed in spam, read the Received chain from bottom to top, and check the Authentication-Results line for spf, dkim, and dmarc pass/fail. That alone tells you why most deliveries failed.
This guide walks through the whole process: where to find full headers, how to decode each header class, and how to use them to diagnose a real spam-folder placement.
Where do you find the full email headers?
Email clients hide headers by default because 99% of users never need them. Here's how to expose the raw source in the clients that matter:
- Gmail (web): Open the message → three-dot menu (top right of the message) → "Show original." You get a formatted view plus the raw source in a "Copy to clipboard" / "Download Original" box. This is the best starting point because Gmail also prints its own verdict summary at the top.
- Outlook (desktop): Open the message in its own window → File → Info → Properties → "Internet headers" box. Cramped and ugly; copy it into a text editor.
- Outlook.com / M365: Three-dot menu → View → View message source.
- Apple Mail: View → Message → Raw Source (⌥⌘U).
- Yahoo Mail: Three-dot menu → "View raw message."
Once you have the raw text, don't try to eyeball it cold. Paste it into the free email header analyzer — it parses the hop chain, flags authentication failures, and highlights the originating IP so you can skip straight to the problem. The rest of this guide is about understanding what the tool is telling you.
How does the Received chain actually work?
The Received header is the backbone of email header analysis. Every server (MTA, or mail transfer agent) that handles the message prepends a new Received line to the top of the header block. So the topmost `Received` line is the final hop into the recipient's mailbox store, and the bottommost is where the message entered the SMTP network.
You read the chain bottom-up to reconstruct the journey. Here's a real-shaped excerpt from a message sent from mail.acmebilling.com to a Gmail user:
Received: by 2002:a05:6e02:1a8f:b0 with SMTP id z15csp2391841laf;
Tue, 11 Aug 2026 09:42:18 -0700 (PDT) ← (4) Gmail's internal handoff
Received: from mail.acmebilling.com (mail.acmebilling.com. [203.0.113.44])
by mx.google.com with ESMTPS id h3si1184123oia.147
(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384);
Tue, 11 Aug 2026 09:42:17 -0700 (PDT) ← (3) Gmail's MX accepted it
Received: from smtp-out-3.acmebilling.com (smtp-out-3.acmebilling.com. [203.0.113.44])
by mail.acmebilling.com with ESMTP id 47BAmGl3021449
for <[email protected]>;
Tue, 11 Aug 2026 16:42:17 +0000 (UTC) ← (2) internal relay
Received: from webapp-01.acme.internal (webapp-01.acme.internal. [10.20.3.17])
by smtp-out-3.acmebilling.com with ESMTPA id 47BAmEkF021448
for <[email protected]>;
Tue, 11 Aug 2026 16:42:16 +0000 (UTC) ← (1) origin: the web appLine by line:
- Bottom line — the web app at
10.20.3.17(a private IP, so this happened inside the sender's network) submitted the message tosmtp-out-3.acmebilling.comusingESMTPA(the A means authenticated submission — a good sign). - The outbound relay passed it internally. Note the
for <[email protected]>— the envelope recipient. - `by mx.google.com` — Gmail's inbound MX accepted the connection from
203.0.113.44over TLS 1.3. This is the hop that matters for IP reputation: Gmail judged the message largely on203.0.113.44and the domains involved. - Gmail's internal delivery to the mailbox.
Two things to check in every chain:
- Time gaps. Compare timestamps hop to hop. If hop (2) happened at 16:40 and hop (3) at 16:42, the message sat in a queue for two minutes — usually a greylisting deferral or provider throttling, not a failure.
- Forged hops. Spammers inject fake
Receivedlines at the bottom to disguise the origin. The trick: trust only the line where your provider's server says it received the mail. Anything below that is attacker-controlled and can be fabricated.
What does the Authentication-Results header tell you?
Authentication-Results is where the receiving server records its verdict on SPF, DKIM, and DMARC (defined in RFC 8601). It's the second place you look after the Received chain. Gmail writes one like this:
Authentication-Results: mx.google.com;
dkim=pass [email protected] header.s=s2026 header.b=kQ9vxTz1;
spf=pass (google.com: domain of [email protected]
designates 203.0.113.44 as permitted sender)
smtp.mailfrom=acmebilling.com;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=acmebilling.comThe fields that matter:
- `dkim=pass [email protected]` — the DKIM signature validated, and the signing domain was
acmebilling.com. If you seedkim=failwithbody hash did not verify, something modified the message in transit (often a forwarding server or an AV scanner adding footers). If you seedkim=none, the sender never signed. - `spf=pass ... smtp.mailfrom=acmebilling.com` — SPF checked the envelope sender (the Return-Path), not the visible From address. The parenthetical shows exactly which IP was authorized.
spf=failorspf=softfail (~all)here means the sending IP isn't in the domain's SPF record. - `dmarc=pass (p=REJECT ...)` — DMARC passed, meaning at least one of SPF or DKIM both passed and aligned with the visible From domain. The
p=REJECTis the domain's published policy.
Critical detail: the verdict is only as trustworthy as who wrote it. The mx.google.com at the top means Gmail itself evaluated these — that's authoritative. An Authentication-Results header claiming mx.attacker.tld wrote it is wallpaper. Anyone can inject a fake one before handing the message off.
One more gotcha: the header shows what the receiving server saw, not what you published. A message can pass SPF at Gmail while your aggregate reports show failures elsewhere. If you want the full picture of how receivers evaluate your domain, you need to know how to read DMARC aggregate reports alongside per-message headers.
Why do ARC headers matter for forwarded mail?
ARC (Authenticated Received Chain, RFC 8617) exists because forwarding breaks authentication. When a mailing list, an alumni forwarder, or a ticketing system relays your message, the forwarding server's IP isn't in your SPF record — so SPF fails at the final destination. If the forwarder also modifies the body (footers, subject tags), DKIM breaks too. Under a p=reject DMARC policy, that legitimate forwarded mail would bounce.
ARC fixes this by letting each forwarder seal the authentication results it saw when it received the message, so the final receiver can look back and say "Gmail saw dmarc=pass before this list mangled it." You'll spot the set of three headers:
ARC-Seal: i=2; a=rsa-sha256; cv=pass; d=lists.example.org; s=arc-2026;
b=Xy7...;
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed;
d=lists.example.org; s=arc-2026; ...
ARC-Authentication-Results: i=2; lists.example.org;
dkim=pass [email protected];
spf=pass smtp.mailfrom=acmebilling.com;
dmarc=pass header.from=acmebilling.comThe i= numbers chain the seals: i=1 is the first forwarder, i=2 the next, and so on. cv=pass in ARC-Seal means the previous links in the chain validated. Gmail and Microsoft both consume ARC when deciding whether to honor an otherwise-failing DMARC verdict.
For senders, ARC is mostly something you observe rather than configure — unless you run a forwarding service yourself. But it explains real mysteries: a message that "should have failed DMARC" landing fine, or a replayed message failing because the ARC chain doesn't match. (Replay abuse of valid DKIM signatures is its own rabbit hole — see DKIM replay attacks explained.)
What are X- headers and which ones should you care about?
Any header starting with X- is non-standard — added by software along the path, carrying vendor-specific data. Most are noise. A few are gold:
- `X-Spam-Status` / `X-Spam-Score` / `X-Spam-Report` — SpamAssassin verdicts. The report lists exactly which rules fired and their scores. This is the closest thing to a direct answer to "why did this land in spam" that you'll ever get from a filter:
X-Spam-Status: Yes, score=6.4 required=5.0 tests=BAYES_99,
HTML_IMAGE_ONLY_16, RDNS_NONE, URIBL_GREY autolearn=noThat one line tells you: Bayesian filter is convinced it's spam (BAYES_99), the message is all image no text, the sending IP has no PTR record, and a URL is on a greylist. Four concrete fixes.
- `X-Google-DKIM-Signature`, `X-Gm-Message-State` — Gmail internals.
X-Gm-Message-Stateincludes an encrypted blob Google uses; you can ignore it. - `X-MS-Exchange-Organization-SCL` — Microsoft's Spam Confidence Level, 0–9. SCL 5+ typically means junk folder; -1 means internal/trusted. If you're debugging why emails land in spam at Microsoft tenants, this number is the verdict.
- `X-Mailer` / `X-Originating-IP` —
X-Originating-IPcan reveal the true client IP behind a webmail send, but it's trivially omitted or faked. Treat it as a hint, not evidence. - Feedback and unsubscribe headers —
X-Feedback-ID(Gmail FBL data for high-volume senders) andList-Unsubscribearen'tX-headers in the latter case, but check forList-Unsubscribe-Post: List-Unsubscribe=One-Clickwhen auditing RFC 8058 one-click unsubscribe compliance.
How do you trace an email's true origin IP?
To trace an email's origin IP, work the Received chain from the top down until you hit the first hop you trust — the one where the recipient's own provider (mx.google.com, outlook.com's protection stack, your company's gateway) accepted the message. The IP in that line's from clause is the last external relay, and for direct sends it's the true origin.
Practical method:
- Find the topmost
Receivedline written by infrastructure you trust (your provider's MX). - Extract the IP from its
fromfield — e.g.,from mail.acmebilling.com (mail.acmebilling.com. [203.0.113.44]). - Ignore everything below lines the sender could have injected.
- Run the IP through a lookup: does its PTR (reverse DNS) match the hostname claimed? Is it on a blocklist? Does it belong to the ESP the sender claims to use?
Paste the whole header block into the header analyzer and it does steps 1–3 automatically, including flagging hops with suspicious hostname/IP mismatches. Then cross-check the IP against your own infrastructure. If the message claims to be from you but the trusted-hop IP isn't yours or your ESP's, you're looking at spoofing — or a forgotten legacy system sending as your domain, which DMARC aggregate data would also reveal.
Diagnosing a spam-folder placement with headers: a worked example
Putting it all together. A support email landed in Gmail spam. Raw headers (trimmed):
Authentication-Results: mx.google.com;
dkim=fail [email protected] header.s=s2024 body hash did not verify;
spf=pass smtp.mailfrom=acmebilling.com;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=acmebilling.com
X-Spam-Status: score=3.1 tests=DKIM_INVALID,HTML_IMAGE_RATIO_02
Received: from mail.acmebilling.com ([203.0.113.44])
by mx.google.com with ESMTPS id ...Read it bottom-up:
- Origin:
203.0.113.44is the company's real outbound relay. Not spoofed. - SPF passes. The IP is authorized.
- DKIM fails with "body hash did not verify" using selector
s2024. The signature the server received doesn't match the body. DMARC still passed because SPF aligned — but Gmail's spam filter took note of the broken signature. - The content rule
HTML_IMAGE_RATIO_02fired too: mostly images.
The story writes itself: the company rotated DKIM keys last month but left an old signing config (s2024) on one relay, and an outbound AV appliance appends a disclaimer footer after signing — breaking the body hash on every message from that path. Fix: align the relay to the current selector and sign after the footer step, not before.
That's the whole craft: every header line is evidence, and the verdicts narrow the search space from "the internet hates us" to one misconfigured relay. If the headers are clean and mail still lands in spam, the problem is reputation or content rather than authentication — at that point, send a deliverability test to get a 0–100 score across authentication, DNS, headers, content, and links and see which category drags you down. And when failures come with SMTP rejection codes rather than silent spam placement, pair header reading with our SMTP error codes explainer.
Frequently asked questions
Sources reviewed
- WillItInbox documentation(product)
Factual review: June 13, 2026 by WillItInbox Editorial.
Keep reading