An email header is the block of fields above the message body. Some are set by the author’s mail software (From, To, Subject, Date, Message-ID, defined in RFC 5322). Others are trace and authentication fields that every server adds as the message moves along. To read one, open the full header, read the Received lines from the bottom up to follow the path, then check Authentication-Results for the SPF, DKIM and DMARC verdicts.
This guide is for senders and developers debugging spam placement, delays, authentication failures and spoofing.
How to view the full header in Gmail, Outlook, Apple Mail and Yahoo
Clients show only a trimmed From, To, Subject and Date by default. These menu paths come from each vendor’s help page:
| Client | Steps |
|---|---|
| Gmail (browser) | Open the email, click More next to Reply, then Show original. A new window shows the full header, with a Copy to clipboard button (Gmail Help). |
| Outlook on the web and new Outlook | Select More actions at the top of the message, then View > View message details (Microsoft Support). |
| Outlook classic (Windows) | Double-click the message to open it, then File > Properties. The header is in the Internet headers box (same Microsoft page). |
| Apple Mail (Mac) | Choose View > Message > All Headers. Use Default Headers to switch back (Apple Support). |
| Yahoo Mail | Open the email, click the More options icon, then View Raw Message (Yahoo Help). |
To sanity-check your reading, Google’s Messageheader tool and Microsoft’s Message Header Analyzer both parse a pasted header and flag delivery delays.
An annotated example header, line by line
The sample below is illustrative. It uses reserved example.com and example.net domains and the documentation IP ranges from RFC 5737, and the values are shortened. Newest lines are at the top, which is how real headers are stacked.
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from mx1.example.net ([192.0.2.10])
by mailstore.example.net with LMTP id Yq3nA
for <[email protected]>; Tue, 29 Sep 2026 09:14:41 +0000
Authentication-Results: mx1.example.net;
dkim=pass [email protected] header.s=s2026 header.b=Xk3q9Lp2;
spf=pass (mx1.example.net: domain of [email protected]
designates 198.51.100.24 as permitted sender)
[email protected];
dmarc=pass (p=REJECT) header.from=example.com
Received: from smtp.example.com (smtp.example.com [198.51.100.24])
by mx1.example.net (Postfix) with ESMTPS id 7B3C9
for <[email protected]>; Tue, 29 Sep 2026 09:14:03 +0000
Received: from app01.example.com (app01.example.com [203.0.113.25])
by smtp.example.com (Postfix) with ESMTPS id 4F1A2
for <[email protected]>; Tue, 29 Sep 2026 09:14:02 +0000
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
s=s2026; h=from:to:subject:date:message-id:list-unsubscribe;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=Xk3q9Lp2...
From: Example News <[email protected]>
To: Sam <[email protected]>
Subject: Your weekly digest
Date: Tue, 29 Sep 2026 09:14:00 +0000
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
List-Unsubscribe: <https://example.com/u/8f3a1c>
Here is what each block tells you.
- Return-Path is the envelope sender (the SMTP
MAIL FROM), added by the final server. It is where bounces go, and it is not the same address as From. Here it is a bounce subdomain,mail.example.com. - Received lines are the trace. Each server that handles the message puts its own line on top, so the bottom one is the first hop. Reading upward:
app01handed the message tosmtp.example.comat 09:14:02, that relay delivered tomx1.example.netat 09:14:03, and the mailbox server stored it at 09:14:41. Thebyhost of one hop should match thefromhost of the next. - Authentication-Results was added by
mx1.example.net, named at the start of the field. All three checks pass. The SPF check ran againstsmtp.mailfrom(the Return-Path domain) and the connecting IP198.51.100.24. The DKIM result reports the signing identity (header.i), the selector (header.s) and a fragment of the signature (header.b). Some receivers printheader.dfor the signing domain instead. RFC 8601 registersheader.d,header.i,header.aandheader.sas DKIM properties, so both forms are legitimate. - DKIM-Signature carries the tags
d=(signing domain),s=(selector) andh=(the headers covered), plusbh=(body hash) andb=(the signature). To find the DKIM selector, reads=, then look ups2026._domainkey.example.comin DNS. Our DKIM signature explainer covers the mechanics. - From, To, Subject, Date, Message-ID are set by the sender’s software. Only Date and From are required by RFC 5322; everything else is optional.
- List-Unsubscribe holds the unsubscribe URL that mail clients turn into an unsubscribe button. The List-Unsubscribe header post covers one-click requirements.
Why this example passes DMARC
DMARC does not only ask whether SPF and DKIM passed. It asks whether the domain they authenticated matches the domain in the visible From header. That match is called alignment. In relaxed mode, the two domains need the same organizational domain. In strict mode they must be identical (RFC 9989, which obsoletes RFC 7489).
Compare the three domains in the sample: From is example.com, SPF authenticated mail.example.com, and DKIM signed as example.com. DKIM aligns exactly. SPF aligns in relaxed mode because mail.example.com shares the organizational domain example.com. A pass needs only one aligned mechanism, and this message has two. For setup steps, see DMARC alignment and the SPF record guide.
Field reference: who adds each header and what it tells you
| Field | Added by | What it tells you | Standard |
|---|---|---|---|
| From | Sender’s mail software | The author’s mailbox, and the domain DMARC aligns against | RFC 5322 |
| Reply-To | Sender’s mail software | Where the author suggests replies go. A mismatch with From is a phishing signal, not proof | RFC 5322 |
| Return-Path | Final receiving server | The envelope sender, copied from MAIL FROM. Bounces go here | RFC 5321 |
| Received | Each server in transit | One hop: which host handed off to which, and when | RFC 5321 |
| Authentication-Results | Receiving server | SPF, DKIM and DMARC verdicts, labeled with the server that produced them | RFC 8601 |
| Received-SPF | Receiving server | The SPF result and the client IP checked. A trace field placed above the receiver’s Received line | RFC 7208 |
| DKIM-Signature | Sending server or ESP | The signature, signing domain, selector and signed header list | RFC 6376 |
| ARC-Seal, ARC-Message-Signature, ARC-Authentication-Results | Each ARC-participating intermediary | A chain of custody: what each handler saw and how authentication looked at that step. Numbered by instance (i=1 up to i=50) | RFC 8617 |
| Message-ID | Sender’s software | A unique identifier for the message. | RFC 5322 |
| Date | Sender’s software | When the author’s client says it was composed. It is set by the sender | RFC 5322 |
| List-Unsubscribe | Sender | URL or mailto for unsubscribing | RFC 2369 |
| X- headers | Any server or app | Non-standard, vendor-specific fields. Meaning depends on the vendor, so check that vendor’s docs before reading anything into one | None |
The RFC 8617 abstract describes it as “an authenticated ‘chain of custody’ for a message”, so a final receiver can see what earlier handlers concluded.
How to read Received headers and where to stop trusting them
Read from the bottom up. Each server prepends its Received line, so the oldest hop sits lowest and the newest sits at the top of the trace block.
Measure delay between hops. Subtract the timestamp of each line from the one above it. In the sample, hop 1 to hop 2 took one second and hop 2 to hop 3 took 38 seconds. A single hop with a large gap points to the server that held the message: a queue, greylisting or content scanning. Convert mixed time zones to UTC first.
Find your trust boundary. RFC 5322 calls trace fields “strictly informational”. A sender can write fake Received lines at the bottom of a message before sending it. What you can rely on are the lines added by servers you trust, typically your own mail provider. Start at the top and stop trusting the trace where the first untrusted server appears. Authentication-Results has the same rule: RFC 8601 requires a receiving server to delete any such field that claims to come from inside its trust boundary but did not come directly from another trusted server. In practice, only believe an Authentication-Results field whose server name (the first token) is your own receiver.
If a hop shows an IP with no sensible hostname, check its reverse DNS to see who operates that host.
Three diagnosis routines
The email went to spam. Open the receiver’s Authentication-Results. Look for fail, softfail, none or neutral on spf, dkim or dmarc. If everything passes, check alignment: compare the From domain with smtp.mailfrom and the DKIM signing domain. A “pass” that is not aligned still fails DMARC. If authentication is clean, the cause is likely reputation or content; see why emails go to spam and our guide to email deliverability.
The email arrived late. Walk the Received lines upward, calculate the gap at each hop, and find the largest one. The server named on the by side of that line, or the one above it, is where the message waited. If the only delay is before the first line, the sending application queued it. If the message never arrived at all, the bounce-back email sent to the Return-Path address is the next place to look.
Suspected spoofing or phishing. Look for: authentication failures, a Return-Path or Reply-To domain that differs from From with no clear reason, and a first hop from an IP or host unrelated to the claimed sender. None alone proves fraud, since legitimate services often use different envelope domains; a combination is the signal.
Frequently Asked Questions
Can email headers be faked?
Yes, partly. Fields the sender controls, such as From, Reply-To, Date and Message-ID, can hold anything, and lower Received lines can be forged. Fields added by your own receiving server, including its Received line and Authentication-Results, are reliable. SPF, DKIM and DMARC exist to detect a forged From domain.
Does an email header show the sender’s IP address?
Usually it shows the IP of the last server that connected to the receiver, in the topmost trusted Received line. That is the sending mail server, not the person’s device.
What is the difference between From and Return-Path?
From is the author address people see. Return-Path is the envelope sender used in the SMTP MAIL FROM command, where bounces are sent. They can differ legitimately, for example when an email service provider handles bounces on a subdomain. DMARC checks whether they align.
How do I find the DKIM selector in a header?
Find the DKIM-Signature field and read the s= tag. The public key lives in DNS at selector._domainkey.domain, where the domain comes from d=. In the example above, that is s2026._domainkey.example.com.
Why read Received headers from the bottom up?
Every server that handles a message adds its own Received line above the existing ones, so the first hop ends up at the bottom and the last hop at the top. Reading upward follows the message in the order it traveled.
Is the Message-ID always unique?
RFC 5322 says the message identifier “MUST be a globally unique identifier” and that the generator must guarantee it. The value is set by the sender, so a forged or reused ID is possible. Use it to search logs, not as proof of authenticity.
I’ve spent my career building software at scale with a soft spot for email: deliverability, lifecycle campaigns, and getting messages to actually land. I started Coldletter to fix what bugged me about transactional and marketing email tools. I’m based in Vancouver.
