How to read email headers
Open the full headers, then read the Received lines from the bottom up to trace the path from sender to you. Next, find the Authentication-Results header added by your own mail system and check spf, dkim and dmarc. Compare the From, Return-Path and DKIM domains. Mismatches and unexpected servers are your clues.
On this page 10 sections
Email headers are the message's travel record. They show which servers handled it, whether it passed SPF, DKIM and DMARC, and what your spam filter decided. Once you know which lines to trust, you can answer most "why did this land in spam?" and "is this real?" questions in a few minutes.
How do I see the full email headers?
Every client hides headers by default. Here's where to find them:
| Client | Steps |
|---|---|
| Gmail (web) | Open the message, select More (three dots) next to Reply, then Show original. Select Copy to clipboard. |
| New Outlook for Windows and Outlook on the web | Open the message, select More actions, then View > View message details. |
| Classic Outlook for Windows | Double-click to open the message in its own window, then File > Properties. Headers are in the Internet headers box. |
| Apple Mail (Mac) | Select the message, then View > Message > All Headers. |
The steps come from Gmail Help, Microsoft Support and Apple's Mail guide. Copy everything, from the first line to the blank line before the message body.
If a user forwards you a suspicious email, the headers you see belong to the forward, not the original. Ask them to send it as an attachment, or to copy the headers using the steps above.
Which email headers can you trust?
This is the most important idea in header analysis. A header is only as trustworthy as the system that wrote it.
- Written by the sender: From, To, Subject, Date, Reply-To, Message-ID, and any Received lines added before the message reached your systems. The sender can put anything here.
- Written by your receiving systems: the top Received lines, Authentication-Results, and filter headers such as Microsoft's X-Forefront-Antispam-Report. These are reliable, as long as you know which servers are yours.
RFC 8601, which defines Authentication-Results, requires a receiving server to delete any copy of that header that claims to come from its own domain but arrived from outside. That stops an attacker pre-stamping dmarc=pass. It only works if you read the header with your provider's name in it.
How to read the Received chain (bottom up)
Each mail server that accepts a message must add a Received line at the top of the header. RFC 5321, section 4.4 says servers must not change or reorder existing lines. So the newest hop is at the top, and the oldest is at the bottom.
A simplified chain:
Received: from mx.filter.example (mx.filter.example [198.51.100.25])
by mail.yourcompany.example with ESMTPS id 4Xk2...; Thu, 8 Oct 2026 09:14:07 +0000
Received: from out.mailer.example (out.mailer.example [203.0.113.40])
by mx.filter.example with ESMTPS id a81f...; Thu, 8 Oct 2026 09:14:05 +0000
Received: from [192.0.2.17] (helo=laptop)
by out.mailer.example with ESMTPSA; Thu, 8 Oct 2026 09:14:03 +0000
Read it from the bottom:
- A device at
192.0.2.17submitted the message toout.mailer.example(theSAinESMTPSAmeans TLS plus SMTP authentication, per RFC 3848). out.mailer.example, at203.0.113.40, delivered it to the filtering server.- The filtering server passed it to your mail server.
Each line has the same parts: from (the host name it claimed and the IP the receiving server actually saw), by (the server that wrote the line), with (the protocol; ESMTPS means TLS was used), and a timestamp.
What to look for in the Received chain
- The handover point. Find the first line written by a server you trust, such as your provider or gateway. The IP in its
frompart is the real connecting server. Everything below it is the sender's claim. - Gaps in time. Compare timestamps hop by hop. A long gap shows where a message was delayed, for example when a server was down and the sender retried.
- Mismatched names. A server that calls itself
mail.bank.examplebut connects from an IP with no matching reverse DNS is worth a closer look. - Unexpected routes. If mail to your domain reaches your mailboxes without passing your filter, someone may be bypassing your MX. See how to block direct-to-tenant delivery.
How to read Authentication-Results
Find the Authentication-Results header that starts with your receiving system's name. In Microsoft 365, a typical one looks like this:
Authentication-Results: spf=pass (sender IP is 203.0.113.40)
smtp.mailfrom=bounce.mailer.example; dkim=pass (signature was verified)
header.d=example.com; dmarc=pass action=none header.from=example.com;
compauth=pass reason=100
The key fields, as described by Microsoft Learn:
| Field | Meaning |
|---|---|
spf= |
Result of SPF for the envelope sender: pass, fail, softfail, neutral, none, temperror or permerror |
smtp.mailfrom= |
The envelope sender's domain, which SPF checked |
dkim= |
Result of DKIM: pass, fail (with a reason) or none |
header.d= |
The domain that signed with DKIM |
dmarc= |
Result of DMARC for the From domain |
header.from= |
The domain in the visible From address |
action= |
What Microsoft did based on the DMARC result, such as oreject (it overrode a reject policy and treated the message as spam) |
compauth= |
Microsoft's composite result: pass, fail, softpass or none |
reason= |
A three-digit code explaining compauth |
Now compare the three domains. In the example, SPF passed for bounce.mailer.example, which doesn't align with example.com. DKIM passed for example.com, which does. That aligned DKIM pass is why DMARC passed. For a refresher on alignment, see SPF vs DKIM vs DMARC.
A few compauth reason codes worth knowing: 000 means explicit DMARC failure against a quarantine or reject policy; 001 means implicit failure, often a sender with weak or missing records; 130 means a trusted ARC sealer overrode a DMARC failure; 905 means DMARC wasn't enforced because of complex routing, such as mail passing through a non-Microsoft service first.
What are ARC headers?
When a mailing list or forwarding service changes a message, SPF and DKIM can break, and DMARC fails. ARC (RFC 8617) lets each intermediary record what the authentication results were when it received the message, then seal that record with a signature.
Each intermediary adds a set of three headers, numbered with i=1, i=2 and so on:
- ARC-Authentication-Results: the results that intermediary saw.
- ARC-Message-Signature: a DKIM-like signature over the message.
- ARC-Seal: a signature over the ARC headers, with
cv=(chain validation) set tonone,passorfail.
ARC is an Experimental RFC. A receiver only uses it if it trusts the sealer. In Microsoft 365, admins can add trusted ARC sealers, which is how compauth reason 130 happens.
Return-Path and Message-ID
Return-Path is added by the server that makes final delivery. It records the envelope sender (the SMTP MAIL FROM address), which is where bounces go (RFC 5321, section 4.4). It's often different from From. Mailing platforms usually use their own bounce domain, which is normal. A Return-Path on a domain with no connection to the From domain, combined with failing DKIM, is a stronger warning sign.
Message-ID is a unique identifier the sending system creates. RFC 5322 says every message should have one. The part after the @ often hints at the system that created it. It's useful for searching logs and message traces, but it's written by the sender, so it proves nothing on its own.
How to read Microsoft 365 anti-spam headers
Microsoft 365 adds two headers to every inbound message. Microsoft Learn documents the useful fields:
| Header and field | What it tells you |
|---|---|
X-Forefront-Antispam-Report: CIP |
Connecting IP address |
CTRY |
Country of the connecting IP, which may differ from the original sender's |
H |
The HELO/EHLO name the connecting server used |
PTR |
Reverse DNS of the source IP |
DIR |
Direction: INB inbound, OUT outbound, INT internal |
SFV |
Spam filtering verdict, such as NSPM (not spam), SPM (spam), SKA (allowed by anti-spam policy), SFE (user's Safe Senders), BLK (user's Blocked Senders) |
CAT |
Policy category applied, such as SPM, HSPM, PHSH, HPHISH, SPOOF, BULK, MALW |
SCL |
Spam confidence level. Microsoft says it doesn't decide filtering in cloud organizations; use CAT and DIR instead |
SFTY |
Impersonation or first-contact safety tip markers, such as 9.19, 9.20, 9.25 |
X-Microsoft-Antispam: BCL |
Bulk complaint level; higher means more likely to draw complaints |
Every SFV and CAT value, plus the compauth reason codes, is listed in Microsoft 365 spam headers explained.
If CIP shows your gateway's IP rather than the original sender's, Microsoft is judging the gateway, not the sender. That's what Enhanced Filtering for Connectors fixes.
A five-minute header check
- Copy the full headers using the steps above.
- Paste them into the Email Header Analyzer to lay out the hops and results.
- Find the first Received line written by a server you trust. Note the connecting IP.
- Read the Authentication-Results from your own system. Check
spf,dkimanddmarc, and comparesmtp.mailfrom,header.dandheader.from. - If you use Microsoft 365, read
CAT,SFVandcompauthto see what the filter decided and why. - Note anything that doesn't fit: a lookalike domain in From, a Reply-To on a different domain, a failed DMARC check, or an unusual route.
What do common header warning signs mean?
| What you see | Likely meaning | What to do |
|---|---|---|
dmarc=fail with header.from on your own domain |
Someone is spoofing your domain, or one of your tools isn't aligned | Check your DMARC reports and sending tools |
dkim=fail (body hash did not verify) |
The message was changed after signing, often by a forwarder or footer | Look for ARC headers or a list server in the chain |
spf=softfail or spf=fail |
The connecting IP isn't in the sender's SPF record | Check whether a forwarder sits in the chain |
| Reply-To on a different domain from From | Replies go somewhere other than the apparent sender | Treat payment or credential requests with suspicion |
SFV:SKA or SFV:SFE on a phishing message |
An allow list let it skip filtering | Review your allow lists |
| Large gap between two timestamps | Delay at that hop | Check that server's queue or availability |
If the message is suspicious, the patterns in what is email spoofing will help you decide what it is.
Next steps
- Practice on a message you know is legitimate, so you recognize your own normal path.
- Bookmark the Email Header Analyzer. It runs in your browser, so nothing is uploaded.
- If legitimate mail keeps landing in junk, work through why did this email land in spam.
- If you use a filtering service such as iBlockSpam, its Received line will appear between the sender and your mailbox. Knowing its host names makes the handover point easy to find.
Browse more guides on running email day to day.
Frequently asked questions
Which Received header is the sender's?
The lowest one, usually. Each server adds its Received line at the top, so the bottom line is the oldest. But the sender's own servers write the lowest lines, and an attacker can fake those. Trust starts at the first line added by a server you control or trust, and works down from there.
Can email headers be faked?
Some can. The sender controls From, Reply-To, Message-ID and any Received lines added before the message reached your systems. They can't forge the Received and Authentication-Results lines your own mail servers add, which is why you read those first.
Why is the Return-Path different from the From address?
Often for a good reason. Return-Path records the envelope sender, where bounces go. Newsletter platforms and ticketing tools commonly use their own bounce domains. It only matters for DMARC if neither SPF nor DKIM produces a pass for a domain aligned with the From address.
What does SCL mean in Microsoft 365 headers?
SCL is the spam confidence level. Microsoft says that in cloud organizations it doesn't decide whether a message is treated as spam. To understand how Microsoft 365 filtered a message, read the CAT and SFV values in X-Forefront-Antispam-Report instead.
Is it safe to paste headers into an online analyzer?
Headers contain names, addresses, internal server names and IP addresses. Use a tool you trust, or one that processes headers locally. Our Email Header Analyzer runs in your browser, so the headers you paste aren't uploaded.
Sources
- RFC 5321: Simple Mail Transfer Protocol, section 4.4 Trace Information
- RFC 5322: Internet Message Format, section 3.6.4 Identification Fields
- RFC 8601: Message Header Field for Indicating Message Authentication Status
- RFC 8617: The Authenticated Received Chain (ARC) Protocol
- Microsoft Learn: Anti-spam message headers
- Microsoft Support: View internet message headers in Outlook
- Gmail Help: Trace an email with its full headers
- Apple Support: Show detailed headers in Mail on Mac (macOS Sequoia)
See how your domain measures up
Run a free Email Health Check: MX, SPF, DKIM, DMARC and transport security in one scan, with the raw records shown. No sign-up.
Keep reading
Microsoft 365 spam headers explained: how to read SFV, CAT, BCL and compauth
Read Microsoft 365 anti-spam headers: what SFV, CAT, SCL, BCL, IPV, SFTY, X-CustomSpam and compauth reason codes mean, and how to find what filtered a message.
9 min read Running email day to dayWhy did this email go to spam or quarantine?
Why an email went to the spam folder or quarantine, what each spam verdict means, how to find the reason in the headers, and how to fix or release the message.
9 min read Running email day to dayHow to stop spammers bypassing your filter by delivering straight to your mail server
Spammers can skip your MX and deliver straight to Microsoft 365, Google Workspace or your server. Lock each one to your filter, test it, roll back.
9 min read