The short answer: Open the message's full headers (Gmail: ⋮ → Show original), then read three things. First, the Authentication-Results line for spf=, dkim= and dmarc= verdicts. Second, the Received lines, which are read bottom to top because each server adds its own line above the previous one. Third, whether From, Return-Path and Reply-To point to the same domain. A mismatch with failed authentication is the classic sign of spoofing.
Headers are a structured log of how a message travelled and what each server concluded about it. Read them by hand, as below, or paste them into the free email header analyzer and get the same answers in a few seconds.
How to Find the Full Headers in Each Email Client
Every client hides headers by default. You want the raw, complete block, not the summary view.
| Client | Steps |
|---|---|
| Gmail (web) | Open the message → ⋮ (More) at the top right → Show original → Copy to clipboard. The top panel also summarises SPF, DKIM and DMARC as PASS or FAIL. |
| Outlook desktop (Windows) | Double-click to open the message in its own window → File → Properties → copy the Internet headers box. |
| Outlook on the web / new Outlook | Open the message → ⋯ (More actions) → View → View message details. |
| Apple Mail (macOS) | Select the message → View → Message → All Headers. For the raw source, choose Raw Source from the same menu. |
| Yahoo Mail | Open the message → ⋯ (More) → View raw message. |
Copy everything above the first blank line; anything below is the message body. If the message was forwarded as an attachment, open the original, because the wrapper's headers describe only the forwarding hop.
A Complete Annotated Example
Below is a realistic header block for a newsletter sent from news@example.com through a third-party sending service. All domains and IPs are reserved for documentation (example.com, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24).
Delivered-To: you@example.net
Received: by 2002:a05:6402:1234:b0:5a1:2b3c with SMTP id x1csp123456edb;
Mon, 05 Oct 2026 09:14:07 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1791216847; cv=none; d=google.com; s=arc-20240605; b=Kf3...
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=...; b=Zq8...
ARC-Authentication-Results: i=1; mx.google.com;
dkim=pass header.i=@example.com header.s=s1 header.b=Qm7xYz1A;
spf=pass (google.com: domain of bounce@mail.example.com designates 198.51.100.25 as permitted sender) smtp.mailfrom=bounce@mail.example.com;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
Return-Path: <bounce@mail.example.com>
Received: from mta25.mail.example.com (mta25.mail.example.com. [198.51.100.25])
by mx.google.com with ESMTPS id d9si1234567qvj.88.2026.10.05.09.14.06
for <you@example.net>
(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
Mon, 05 Oct 2026 09:14:06 -0700 (PDT)
Authentication-Results: mx.google.com;
dkim=pass header.i=@example.com header.s=s1 header.b=Qm7xYz1A;
spf=pass (google.com: domain of bounce@mail.example.com designates 198.51.100.25 as permitted sender) smtp.mailfrom=bounce@mail.example.com;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
Received: from app01.internal.example.com (app01.internal.example.com [192.0.2.44])
by mta25.mail.example.com (Postfix) with ESMTPS id 4F2A31200A5
for <you@example.net>; Mon, 05 Oct 2026 16:14:04 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s1;
t=1791216844; h=from:to:subject:date:message-id:list-unsubscribe;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=Qm7xYz1A8k...truncated...
From: Example News <news@example.com>
To: you@example.net
Subject: Your October update
Date: Mon, 05 Oct 2026 16:14:03 +0000
Message-ID: <20261005161403.4F2A31200A5@mta25.mail.example.com>
List-Unsubscribe: <https://example.com/u/abc123>, <mailto:unsub@example.com?subject=abc123>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="b1_8f2c"
X-Mailer: ExampleSend 4.2
Step 1: Read the Received chain bottom-up
Each server that handles a message adds a Received line at the top of the block, so the chronological story runs from the bottom line upward.
- Bottom
Received:app01.internal.example.com [192.0.2.44]handed the message tomta25.mail.example.comat 16:14:04 UTC. This is the origin. - Top
Received:mta25.mail.example.com [198.51.100.25]delivered it to Google'smx.google.comover TLS 1.3 at 09:14:06 PDT, which is 16:14:06 UTC. Two seconds elapsed, so there was no queueing delay.
The text in square brackets is the IP address the receiving server actually saw. It is the most reliable part of any Received line because the receiver recorded it. The hostname before the bracket is whatever the sender claimed in its HELO, which can be faked. Only the line added by your own provider is fully trustworthy. Lines further down were written by servers you do not control, so a forger can invent them.
Large gaps between timestamps show where delay occurred. Convert time zones to UTC before subtracting.
Step 2: Authentication-Results
This is the line most people need. Authentication-Results (RFC 8601) is added by the receiving server and records what it checked:
spf=pass: the connecting IP198.51.100.25is authorised by the SPF record ofmail.example.com, thesmtp.mailfrom(envelope sender) domain.dkim=pass header.i=@example.com header.s=s1: a DKIM signature fromexample.com, selectors1, verified against the public key in DNS.dmarc=pass (p=REJECT ...) header.from=example.com: at least one of SPF or DKIM passed and aligned with the visible From domain. Gmail also shows the domain's published policy.
Values include pass, fail, softfail, neutral, none, temperror and permerror. An Authentication-Results line written by your own mailbox provider is reliable. One that arrived pre-baked from an unknown server is not, since anyone can write that text. The mx.google.com after the first semicolon is the authserv-id, the server that claims the verdict. Check it matches your provider.
Step 3: The DKIM-Signature tags
The DKIM-Signature header is added by the sender's system. The tags worth recognising:
| Tag | Meaning |
|---|---|
d=example.com |
The signing domain. For DMARC alignment this must match (or be a subdomain of) the From domain. |
s=s1 |
The selector. The public key lives at s1._domainkey.example.com. |
a=rsa-sha256 |
Signing algorithm. Avoid rsa-sha1. |
c=relaxed/relaxed |
Canonicalisation for headers/body, which controls how tolerant verification is of whitespace changes. |
h= |
The list of headers covered by the signature. From must be included. |
bh= |
Hash of the message body. If a mailing list adds a footer, this stops matching. |
b= |
The signature itself, computed over the signed headers. |
t= |
Signing timestamp (Unix time). |
A dkim=fail with body hash did not verify means the body changed after signing. A failure that mentions a missing key points to a bad selector or DNS record. See DKIM signature failed for fixes, or look up a selector with the DKIM checker.
Step 4: Return-Path versus From
Three "from" addresses exist, and confusing them is how most spoofing hides:
Fromis what people see. DMARC protects this domain.Return-Pathis the envelope sender used for bounces and for SPF. Added by the final receiving server from the SMTPMAIL FROM.Reply-Tois where your reply goes, if present.
In the example, Return-Path is bounce@mail.example.com while From is news@example.com. That difference is normal for third-party senders and still passes DMARC through relaxed SPF alignment (a subdomain of the same organisational domain). A Return-Path on an unrelated domain is only a problem when DKIM does not rescue alignment.
Step 5: ARC headers
ARC-Seal, ARC-Message-Signature and ARC-Authentication-Results (RFC 8617) record authentication results at each forwarding hop. They matter when a mailing list or forwarder modifies a message and breaks DKIM or SPF. i=1 is the hop number. cv=none on the first seal means the chain is starting, and cv=pass on later ones means earlier seals validated. Receivers may weigh ARC when a forwarded message now fails DMARC, but it is a hint, not an override.
Step 6: Message-ID, List headers and X-headers
- Message-ID should be unique and end in a domain that makes sense for the sender, like
@mta25.mail.example.com. Alocalhostdomain or one contradicting the claimed sender is a minor red flag. List-UnsubscribeandList-Unsubscribe-Postshow whether the sender supports one-click unsubscribe, which bulk senders now need.- X-headers are non-standard and added by individual systems. Common ones:
X-Mailer,X-Originating-IP,X-Spam-Status: No, score=0.4 required=5.0 tests=...(SpamAssassin-style verdict and threshold),X-Spam-Score.
Key Headers at a Glance
| Header | Added by | What it tells you |
|---|---|---|
Received |
Each server | Route, timing and connecting IP per hop (read bottom-up) |
Authentication-Results |
Receiving server | SPF, DKIM, DMARC verdicts |
DKIM-Signature |
Sending system | Signing domain, selector, signed headers |
Return-Path |
Final receiver | Envelope sender used for SPF and bounces |
From / Reply-To |
Sender | Displayed identity and reply target |
Message-ID |
Originating system | Unique ID, hints at originating infrastructure |
ARC-* |
Forwarders/receivers | Auth results preserved across forwarding |
X-Spam-Status / X-Spam-Score |
Receiving filter | Spam verdict and score |
How to Spot Spoofing and Phishing in Headers
No single check is conclusive; look for a pattern.
- Authentication-Results shows
dmarc=fail, or both SPF and DKIM failing for the From domain. Combined with an unexpected message, this is strong evidence. - From domain and Return-Path domain differ with no DKIM alignment. Legitimate third-party senders align through DKIM, so a mismatch plus a DKIM signature from the sender's own domain (
d=sendgrid.net, say) does not align with the From domain. - Reply-To points to another domain, typically a free mailbox like Gmail. Common in business email compromise.
- Display name impersonates someone while the address is unrelated. Headers show the real address even if the client hides it.
- The first
Receivedhop is a residential IP, a hosting provider, or a country that doesn't fit the claimed sender. Authentication-Resultsis missing, or its authserv-id isn't your provider's.- Look-alike domain:
examp1e.com,example-support.com. DMARC passes for a domain the attacker owns, so passing authentication alone does not prove trust.
A pass proves only that the message came from the domain it claims. A failure does not always mean fraud: forwarding, mailing lists and misconfigured sending tools all cause failures. The SPF vs DKIM vs DMARC explainer covers why.
What the Free Email Header Analyzer Parses
The email header analyzer takes pasted headers and extracts:
spf,dkim,dmarcandarcresults fromAuthentication-Results- Each
Receivedhop with its from-host, by-host, timestamp and the delay since the previous hop, plus total hop count and total delay From,Reply-To,Return-Path,Message-ID,Subject,Date,X-Originating-IP,X-Spam-ScoreandX-Spam-Status- Flags for SPF/DKIM/DMARC failures, domain mismatches between From, Reply-To and Return-Path, a spam score above 5, and unusually high hop counts (over 10)
It then gives an overall pass, warn or fail verdict with recommendations. Two limits to know: it reads the results the receiving server recorded, so it does not re-run DKIM verification itself, and it can only be as trustworthy as the headers you paste. To check the sender's current DNS, pair it with the SPF checker, DKIM checker and DMARC checker.
Frequently Asked Questions
What is an email header analyzer?
It parses the raw header block of an email and presents the route, authentication results and warning signs in plain language.
Why are Received headers read from the bottom up?
Each mail server inserts its Received line above the existing ones. The oldest hop therefore sits at the bottom and the final delivery sits at the top.
Can email headers be faked?
Yes, anything the sender's system wrote, including lower Received lines and X- headers, can be forged. The lines added by your own receiving server, especially Authentication-Results, are the reliable ones.
What does dmarc=fail in the headers mean?
Neither SPF nor DKIM passed with a domain aligned to the From address. Depending on the sender's policy, the message may be quarantined or rejected. If you own the domain, find the failing source in your DMARC aggregate reports.
How do I find the sender's IP address in an email?
Look at the Received line closest to the sender, usually the lowest one you can trust, and read the IP in square brackets. Gmail's Show original summary also shows it beside the SPF result.
Next step: Paste a suspicious message into the email header analyzer. If you manage a domain whose mail is failing, run the free email audit to check SPF, DKIM and DMARC together.