How to Read Email Headers: Find the Real Sender, the Delivery Route and Why Mail Went to Spam
To read email headers, open the full message source (in Gmail: the ⋮ menu → Show original), find the Received lines and read them from the bottom up — that is the route the message took, server by server. Then look at Authentication-Results: it records whether SPF, DKIM and DMARC passed when your mail server accepted the message. Those two blocks answer the three questions people usually have: where did this email really come from, is the sender genuine, and why did it land in spam.
What email headers are and which ones matter
Every email has two parts: headers and body. The headers are a list of Name: value lines. Some are written by the sender’s mail program (From, Subject, Date), others are added by every server on the way (Received) and by the receiving server (Return-Path, Authentication-Results). Your mail client shows only a few of them. The full list usually runs to dozens of lines, and most of it is noise. These are the ones worth knowing:
| Header | Who writes it | What it tells you |
|---|---|---|
From | Sender’s software | The address you see. Easy to fake on its own — that is what DMARC exists for. |
Reply-To | Sender’s software | Where your reply will go. A different domain than From is normal for support desks and newsletters, suspicious in an unexpected request. |
Return-Path | Final receiving server | The envelope sender (bounce address). SPF is checked against this domain, not against From. |
Message-ID | Sender’s software or server | A unique ID. Its domain often hints at the system that created the message. |
Received | Every server on the route | One line per hop: who handed the message to whom, from which IP, when, with or without TLS. |
Authentication-Results | Receiving server | SPF, DKIM and DMARC results as the receiver saw them at delivery time. |
Received-SPF | Some receiving servers | A separate line with the SPF result and the IP that was checked. |
DKIM-Signature | Signing server | The signature: d= is the signing domain, s= the selector, h= the list of signed headers. |
ARC-Seal, ARC-Message-Signature, ARC-Authentication-Results | Intermediaries (forwarders, mailing lists) | A record of the checks an intermediary saw before it forwarded the message; cv= in ARC-Seal shows whether the chain is intact. |
X-… headers | Spam filters, mail systems | Vendor-specific: for example X-Spam-Status and X-Spam-Score from SpamAssassin, X-MS-Exchange-Organization-SCL or X-Forefront-Antispam-Report from Microsoft 365. |
How to view email headers in Gmail, Outlook, Apple Mail and others
- Gmail (web): open the message → ⋮ → Show original. The page starts with a short summary (SPF, DKIM and DMARC verdicts), followed by the raw headers. Download original saves an .eml file.
- Outlook for Windows: open the message in its own window → File → Properties → Internet headers.
- Outlook on the web and the new Outlook: the … menu on the message → View → View message details.
- Apple Mail: View → Message → All Headers, or Raw Source for everything.
- Thunderbird: Ctrl+U (⌘U on a Mac) opens the message source.
- Yahoo Mail: … → View raw message.
Menus change between versions, so if a path does not match, search the client’s help for “message source” or “internet headers”. Two practical notes: most phone apps do not show full headers, so use a computer; and a copy from your own Sent folder is useless for diagnosis — it has not travelled anywhere yet, so there are no Received lines from the recipient’s side and no check results.
Step by step: reading a header block
- Start with the visible identity. Note the From address, the Reply-To (if any) and the Return-Path. Three different domains are a reason to look closer, not a verdict.
- Find the top Authentication-Results. If there are several, the top one was added by your own provider — trust that one. Read
spf=,dkim=anddmarc=. - Check alignment. DMARC only counts SPF or DKIM if their domain matches the From domain (see below).
- Read the Received lines bottom-up. The lowest line is the earliest hop; the top line is your mailbox.
- Find the first public IP the trusted part of the chain received the message from — that is the best available “sender IP”.
- Look at spam filter headers to see how the message was scored and by whom.
Reading the Received chain from the bottom up
Each server adds its Received line on top of the existing ones, so the order is reversed. A simplified chain might look like this:
Received: by 2002:a05:6000:1a8b with SMTP id …;
Tue, 13 Oct 2026 09:14:07 -0700 (PDT)
Received: from mail.shop.example (mail.shop.example. [203.0.113.40])
by mx.google.com with ESMTPS id …
for <[email protected]>; Tue, 13 Oct 2026 09:14:05 -0700 (PDT)
Received: from app-07.internal (unknown [10.0.4.17])
by mail.shop.example (Postfix) with ESMTP id 4F2A1;
Tue, 13 Oct 2026 16:13:58 +0000 (UTC)
Bottom line: an internal machine with a private IP (10.0.4.17) handed the message to the shop’s mail server. Middle line: Google’s MX accepted it from 203.0.113.40 over TLS (ESMTPS). Top line: internal delivery into the mailbox. In each line, from is how the sending host introduced itself, the part in brackets is what the receiving server actually saw (reverse DNS name and IP), and by is the receiving server. The IP in square brackets was recorded by the receiver, so it is more reliable than the name after from.
One rule matters more than all the others: only the lines added by servers you trust are reliable. Anyone can put fake Received lines into a message before sending it. Start at the top, follow the chain down while the servers belong to your provider, and the hop where your provider accepted the message is where the reliable part ends.
Delays between hops
Compare the timestamps of neighbouring hops after converting them to one time zone (note the different offsets in the example: −0700 and +0000). Seconds per hop are normal. Minutes or hours usually mean greylisting (the receiver asked the sender to retry later), a queue on the sending side, content scanning or retries after a temporary error. A negative delay does not mean the message travelled back in time — it means two servers’ clocks disagree.
How to find the real sender IP
The “origin IP” is the first public address in the trusted part of the Received chain — the machine your provider (or the provider’s first relay) accepted the message from. Private ranges such as 10.x.x.x, 172.16–31.x.x and 192.168.x.x are internal networks and say nothing about location. Keep the limits in mind:
- If someone writes from Gmail, Outlook.com or another webmail service, the first public hop is that provider’s server. The person’s own home or office IP is usually not in the headers at all.
- Corporate servers and some providers do add the client IP (sometimes in a separate X- header). It can be a VPN, a mobile carrier’s gateway or an office proxy.
- IP geolocation is approximate — it shows where the address is registered or routed, not where a person sits.
Once you have the IP, check it against IP blacklists and look up its owner with IP geolocation or reverse DNS. If it is listed, the article why is my IP blacklisted explains what the lists mean and how delisting works.
SPF, DKIM and DMARC results and alignment
A typical line from Gmail looks like this:
Authentication-Results: mx.google.com;
dkim=pass [email protected] header.s=s1 header.b=Ab12Cd34;
spf=pass (google.com: domain of [email protected] designates 203.0.113.40 as permitted sender) [email protected];
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=shop.example
What each part says:
- spf=pass — the IP that delivered the message is allowed by the SPF record of the Return-Path domain (
smtp.mailfrom).softfailandfailmean it is not allowed;permerrormeans the record itself is broken. - dkim=pass — the signature from
header.i/d=matched the key published in DNS under selectorheader.s.failmeans the message was changed on the way or the key does not match. - dmarc=pass — at least one of SPF or DKIM passed for a domain aligned with From. The
p=part shows the domain’s published policy.
Alignment is where most confusion comes from. SPF checks the Return-Path domain and DKIM checks the d= domain, but people see the From domain. DMARC ties them together: with relaxed alignment (the default) mail.shop.example and shop.example count as a match because they share the organisational domain; with strict alignment they must be identical. That is why you can see spf=pass and dkim=pass next to dmarc=fail: both checks passed, but for a mailing service’s domain instead of yours.
To check what a domain publishes right now, use the SPF checker, the DKIM checker (take the selector from s= in DKIM-Signature) and the DMARC checker. How the three fit together is covered in SPF, DKIM and DMARC explained, and selectors in what is a DKIM record and selector.
Task: why did my email go to spam?
Ask the recipient for the headers of the message that landed in spam (your Sent copy will not help), then go through this list:
- Authentication. Any
fail,softfailornonefor SPF, DKIM or DMARC is the first thing to fix. - Alignment. If DMARC fails while SPF and DKIM pass, set up a custom bounce domain and DKIM signing with your own domain in your email service.
- Sending IP. Check the first public IP from your side against blacklists.
- Spam filter verdicts. SpamAssassin lists the rules that fired in
X-Spam-Status; in Microsoft 365, an SCL value of 5 or higher means the message was classified as spam. - Bulk mail headers. Newsletters without a working
List-Unsubscribeheader are treated less kindly by large mailbox providers.
If everything passes and the IP is clean, the cause is usually reputation or content, which headers do not show directly.
Task: is the sender genuine? Signs of spoofing and phishing
- The message claims to be from a bank or a well-known service, but DMARC fails or is missing.
- Reply-To points to a different domain, especially a free mailbox.
- The display name contains an address that differs from the real one:
"[email protected]" <[email protected]>. - A look-alike domain in From or Return-Path (a digit instead of a letter, an extra word, a different TLD).
- The first public IP belongs to a network that has nothing to do with the claimed sender.
- A spam filter on the way has already flagged the message.
Privacy: be careful when you share headers
Headers often contain more personal data than the visible message: your full address and sometimes other recipients, internal host names, IP addresses, the sender’s mail program and personal unsubscribe or tracking links. Before posting headers in a forum or a ticket, replace your address and any long tokens in links with placeholders, but keep Received, Authentication-Results and DKIM-Signature intact — without them nobody can diagnose anything. Prefer tools that process headers locally rather than ones that store what you paste.
Common mistakes
- Reading Received lines top-down and taking the recipient’s server for the sender.
- Trusting every Received line, including ones added before the message reached a trusted server.
- Treating
spf=passas proof that From is genuine — SPF checks Return-Path. - Diagnosing a spam problem from the Sent folder copy.
- Comparing timestamps without converting time zones.
Analyse headers with the PromoPilot tool
Paste the headers or drop an .eml file into the Email Header Analyzer. It lists the hops bottom-up with delays in UTC, points out the slowest step and clock mismatches, shows the first public IP in the chain, the SPF, DKIM, DMARC and ARC results the receiver recorded, alignment between From, Return-Path and DKIM d=, spam filter headers, one-click unsubscribe headers and spoofing signs such as a different Reply-To or an address in the display name.
What it does not do:
- It does not re-verify DKIM signatures. That needs the full message and DNS as it was at delivery, so the tool shows what the receiving server recorded and checks the domains itself.
- It does not look up IPs or domains on its own: the links next to each IP lead to our blacklist, geolocation and reverse DNS checks if you want to run them.
- It cannot read Outlook .msg files (a binary format) — copy the Internet headers or save the message as .eml.
- The organisational domain for alignment is determined approximately, without the full Public Suffix List.
Parsing runs in JavaScript in your browser; the headers are not sent to our server. There is no daily limit; one run accepts up to 2 MB of text (from an .eml the first 1 MB is read).