How to read email headers, from Received to ARC
Read full email headers step by step: Received lines bottom-up, Return-Path, Authentication-Results, DKIM-Signature, ARC, spam verdicts and safe sharing.
By Exmoor Software7 min read
Your mail app shows four header fields — From, To, Subject, Date — and hides the rest. The hidden ones record which servers handled the message, whether it passed SPF, DKIM and DMARC, and sometimes why it was filtered as spam. This guide explains how to read them, which ones to trust, and how to export and share them safely.
The quick route: export the full headers (instructions near the end) and paste them into the email header analyzer, which parses them in your browser without uploading anything.
Headers are a stack: read them bottom-up
Every server that accepts a message adds its trace lines at the top. RFC 5321 requires each SMTP server to insert its Received line at the beginning and forbids changing, deleting or reordering existing ones. So the newest lines are at the top, and the fields written by the sender’s mail program — From, To, Subject, Date, Message-ID — are further down. To follow the journey, read the Received headers from the bottom up.
A simplified message as it arrived for anna@example.net:
Return-Path: <bounces+7f3a@mail.example.com>
Delivered-To: anna@example.net
Authentication-Results: mx.example.net;
spf=pass smtp.mailfrom=mail.example.com;
dkim=pass header.d=example.com header.s=s2026;
dmarc=pass header.from=example.com
Received: from out1.mail.example.com (out1.mail.example.com [192.0.2.25])
by mx.example.net with ESMTPS id 4Q8fKx2
for <anna@example.net>; Fri, 23 Oct 2026 09:14:05 +0000
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s2026;
h=from:to:subject:date:message-id; bh=…; b=…
Received: from app1.example.com (app1.example.com [198.51.100.10])
by out1.mail.example.com with ESMTPSA id 91c2d0;
Fri, 23 Oct 2026 09:14:03 +0000
From: Example Shop <orders@example.com>
To: anna@example.net
Subject: Your order 1042
Date: Fri, 23 Oct 2026 09:14:02 +0000
Message-ID: <20261023091402.7f3a@example.com>
Bottom-up: the shop’s server app1 submitted the message to its outgoing server out1, which signed it with DKIM and delivered it to mx.example.net, which checked authentication and stored it.
Received: one line per hop
| Part | Meaning |
|---|---|
from out1.mail.example.com | name the sending server gave in EHLO |
(… [192.0.2.25]) | what the receiver saw: usually reverse-DNS name and IP of the connection |
by mx.example.net | server that accepted the message and wrote the line |
with ESMTPS | ESMTPS = STARTTLS used, ESMTPA = authenticated, ESMTPSA = both (RFC 3848); plain ESMTP or SMTP = no TLS |
id 4Q8fKx2 | queue ID — quote it when asking that server’s operator |
for <…> | optional: the recipient of this copy |
date after ; | when that server accepted the message |
What to look for:
- Delays. Subtract consecutive timestamps. A long gap on one hop points to that server: queueing, greylisting, retries. A small negative delay usually means a server clock is off.
- The hand-over. Find the lowest
Receivedline written by your own mail provider. Itsfrompart is the server that handed the message over — the true origin as far as you can verify it. - The rest are claims. Lines below the hand-over were written by servers you don’t control, and a sender can invent hops to mislead you.
Return-Path: where bounces go
The server making the final delivery adds Return-Path with the envelope sender — the MAIL FROM address of the SMTP session (RFC 5321). Bounces go there, and it is the domain SPF checks. It often differs from From, which is fine as long as DMARC is satisfied through DKIM or an aligned bounce domain (DMARC alignment). Return-Path: <> is an empty envelope sender, used by bounces themselves so they can’t cause further bounces; SPF then checks the HELO name.
Authentication-Results: the verdict
Authentication-Results (RFC 8601) records what a receiving server checked and the outcome (see the example above):
- The first item,
mx.example.net, is the authserv-id: it identifies the service that did the checks. - Each result is
method=resultplus properties:smtp.mailfrom(envelope domain checked by SPF),header.dandheader.s(DKIM signing domain and selector),header.i(DKIM identity),header.from(From domain evaluated by DMARC). - Results:
pass,fail,softfail(SPF),neutral,none,temperror(temporary, often DNS),permerror(permanent, such as a broken record) andpolicy(the check passed, but local policy didn’t accept it). Parentheses hold free-text comments.
You may also see arc= (below), iprev= (reverse DNS of the connecting IP) and auth= (SMTP authentication). Microsoft 365 adds compauth=, its composite verdict for the From domain, with a reason= code documented by Microsoft.
Which one to trust
A message can carry several of these headers: your provider’s, those of servers it passed earlier, and possibly fakes added by the sender. RFC 8601 resolves this with the authserv-id: border servers must remove existing headers that claim their own organization’s identifier, and software should use only results whose authserv-id belongs to its own organization. In practice:
- Find the
Receivedline where your provider accepted the message from outside. - Use the
Authentication-Resultsyour provider wrote — normally just above it, at or near the top. - Treat the others as history: what an earlier hop saw, not what your provider decided.
The header analyzer groups results by the reporting authserv-id. It reads the recorded verdicts; it doesn’t re-verify signatures or query DNS.
DKIM-Signature: who signed what
| Tag | Meaning |
|---|---|
d= | signing domain — compare with the From domain for alignment |
s= | selector; the key is at s2026._domainkey.example.com (DKIM checker) |
a= | rsa-sha256 or ed25519-sha256; verifiers must not accept rsa-sha1 |
c= | header/body canonicalization: relaxed tolerates whitespace changes, simple almost none |
h= | signed header fields; from must be among them |
bh=, b= | body hash, signature |
i=, t=, x= | optional identity, signing time, expiry |
l= | optional body length; content appended beyond it isn’t covered — a known weakness |
Two signatures — your domain’s and the sending service’s — are common; DMARC needs one that passes and aligns. The signature only claims who signed; whether it verified is in Authentication-Results. More in how DKIM works.
ARC: results that survive forwarding
When a mailing list adds a footer or a service forwards a message, DKIM can break and SPF fails, so DMARC fails although the original was fine. ARC, the Authenticated Received Chain (RFC 8617, an Experimental RFC), lets each intermediary record what it saw before changing anything. It adds an ARC set of three headers sharing the instance number i=:
ARC-Seal: i=1; a=rsa-sha256; cv=none; d=lists.example.org; s=arc1; t=…; b=…
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.example.org;
s=arc1; h=from:to:subject:date; bh=…; b=…
ARC-Authentication-Results: i=1; mx.lists.example.org;
spf=pass smtp.mailfrom=mail.example.com;
dkim=pass header.d=example.com; dmarc=pass header.from=example.com
- ARC-Authentication-Results: the results the intermediary got on arrival —
Authentication-Resultssyntax plusi=. - ARC-Message-Signature: a DKIM-like signature of the message as passed on.
- ARC-Seal: a signature over the ARC headers;
cv=records the chain state the sealer received:none(no earlier sets),passorfail.
The next intermediary adds i=2, and so on, up to 50 sets. The final receiver records the outcome, such as arc=pass, in its own Authentication-Results.
ARC proves which intermediaries handled a message, not that they are honest. Each receiver decides which sealers it trusts, and only then may it accept their results despite a DMARC failure. Senders can’t add ARC to other people’s forwarding; signing everything with DKIM limits the damage.
Spam verdict headers
Some filters write a verdict into the message, in non-standard X- headers:
- SpamAssassin, common at hosting providers:
X-Spam-Status: Yes, score=7.4 required=5.0 tests=…andX-Spam-Flag: YES. The test names explain the score. - Microsoft 365:
X-Forefront-Antispam-ReportwithSFV:SPM(spam) orSFV:NSPM(not spam),CAT:(policy applied, such asSPM,PHSH,BULK) andSCL:(spam confidence level);X-Microsoft-AntispamcarriesBCL:(bulk complaint level). Microsoft notes that in cloud organizations the SCL value doesn’t determine whether a message is treated as spam or what happens to it; to see how a message was filtered, it points toCATandDIR(the message direction) instead.
Not every provider exposes a verdict, and the copy in the sender’s Sent folder never shows what the recipient’s server decided — ask the recipient for their headers. Common causes are covered in why emails go to spam.
How to get the full headers
- Gmail (web): open the message, ⋮ (More) next to Reply → Show original, then Copy to clipboard or Download original.
- Outlook on the web, Outlook.com, new Outlook for Windows: More actions (⋯) → View → View message details.
- Classic Outlook for Windows: open the message in its own window, File → Properties; see the Internet headers box.
- Apple Mail on Mac: View → Message → All Headers, or Raw Source in the same menu for the complete message.
- Thunderbird: View → Message Source (Ctrl+U, ⌘U on Mac).
Most phone apps don’t show headers; use webmail or a desktop client. Headers end at the first empty line; the analyzer accepts the headers alone or the whole source.
Sharing headers safely
Headers reveal more than they seem: names and addresses of the sender and all recipients; IP addresses and internal host names of servers and, with some providers, of the sender’s device; the subject and Message-ID; and personal tokens such as the List-Unsubscribe link — which works for anyone who opens it.
Before posting headers in a forum or a ticket:
- Share the headers only, not the source — the body may hold personal data, tokens and attachments.
- Replace addresses consistently (
anna@example.net→user@example.net) so the path still makes sense. - Remove
List-UnsubscribeURLs and other links with tokens. - Keep
Received,Authentication-Results,DKIM-SignatureandARC-*intact; longb=values can be shortened.
References
- RFC 5321 — Simple Mail Transfer Protocol (trace information)
- RFC 5322 — Internet Message Format
- RFC 3848 — ESMTP and LMTP Transmission Types Registration
- RFC 8601 — Message Header Field for Indicating Message Authentication Status
- RFC 6376 — DKIM Signatures
- RFC 8617 — The Authenticated Received Chain (ARC) Protocol
- Microsoft — Anti-spam message headers
- Microsoft — View internet message headers in Outlook
- Google — Trace an email with its full headers