Every email carries a second, hidden letter stapled to the front of it. It records which servers passed the message along, when, and whether the sender was allowed to use the address in the From line. Most people never look at it. If you have ever received a "your account will be closed" message that looked a little too real, it is the one thing worth looking at.
This guide shows you how to read that hidden part, the header, line by line. Then it shows what we found when we checked how the 1,000 most popular websites protect their own addresses from being forged.
Step 1: Get the full header
Your email app hides the header by default. To see it:
- Gmail: open the message, click the three dots next to Reply, choose Show original.
- Outlook on the web: open the message, click the three dots, choose View, then View message source.
- Outlook desktop: open the message in its own window, choose File, then Properties, and look at the Internet headers box.
- Apple Mail: choose View, then Message, then All Headers.
- iPhone and Android mail apps: most cannot show headers. Open the same mailbox on a computer.
Copy everything from the top of the message down to the first blank line. That block is the header. You can paste it into our email header analyzer, which lays it out for you and runs in your browser, or read it by hand with the steps below.
Step 2: Read the Received lines from the bottom up
Every server that handles a message adds a Received line to the top. So the newest line is first and the oldest is last. To follow the message from sender to you, read from the bottom up.
Here is a trimmed header from a normal message sent from a company mailbox to a Gmail address. The addresses use the ranges reserved for documentation, so they will not point to anyone real.
Received: by 2002:a05:6a10:8f0e:b0:5f2 with SMTP id k14csp1182;
Thu, 22 Oct 2026 09:14:07 -0700 (PDT)
Received: from mail.yourwebsite.com (mail.yourwebsite.com. [203.0.113.25])
by mx.google.com with ESMTPS id a7si2210;
Thu, 22 Oct 2026 09:14:06 -0700 (PDT)
Authentication-Results: mx.google.com;
dkim=pass [email protected] header.s=mail2026;
spf=pass (google.com: domain of [email protected] designates 203.0.113.25 as permitted sender) [email protected];
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=yourwebsite.com
Return-Path: <[email protected]>
From: Outline Technologies Billing <[email protected]>
To: [email protected]
Subject: Your October invoice
Message-ID: <[email protected]>
Date: Thu, 22 Oct 2026 16:14:04 +0000
Reading it from the bottom:
- Date and Message-ID were written by the sender's mail server. The Message-ID ends in mail.yourwebsite.com, which matches the domain in From. That is a good sign but easy to fake.
- The second Received line says Google's server (mx.google.com) received the message from mail.yourwebsite.com at 203.0.113.25. Google wrote this line, so you can trust it. This is the most important line in the header: it is the first server you know is real, and it tells you exactly where the message came from.
- The top Received line is Google moving the message inside its own systems. Not interesting.
The rule: read up from the bottom until you reach the first line written by your own provider. Everything below that line was written by the sender and can be invented. Everything above it was written by servers you trust.
Step 3: Check Authentication-Results
This one line does most of the work. Your mail provider ran three checks and wrote the results down:
| Check | What it asks | What you want to see |
|---|---|---|
| SPF | Is the sending server on the domain's list of allowed servers? | spf=pass |
| DKIM | Does the message carry a valid signature from the domain? | dkim=pass |
| DMARC | Does SPF or DKIM pass for the same domain shown in From? | dmarc=pass |
In the example, all three pass and the DMARC part shows p=REJECT, meaning the domain owner asked receivers to bounce anything that fails. That is about as strong as email gets.
A forged message usually looks like this instead:
Authentication-Results: mx.google.com;
spf=fail (google.com: domain of [email protected] does not designate 198.51.100.77 as permitted sender) [email protected];
dkim=none;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yourwebsite.com
SPF failed because the server at 198.51.100.77 is not allowed to send for the domain. There is no DKIM signature. DMARC failed, but the domain's policy is p=NONE, so the receiver delivered it anyway. This is exactly the gap that lets convincing fakes into inboxes.
Step 4: Look for the usual warning signs
- From and Return-Path use different domains and DMARC did not pass. Some newsletters do this legitimately through a mailing service, but then DKIM should still pass for the From domain.
- Reply-To points somewhere else, often a free webmail address. Your reply would go to the attacker, not the company.
- The first trusted Received line names a server or network that has nothing to do with the company, such as a residential connection in another country. You can paste the IP into our IP lookup to see the network and country.
- The display name contains an email address that differs from the real one, for example a name like "[email protected]" sitting in front of a completely different address.
- The Date is far from the first trusted Received time. A message that claims to be from last week but arrived a minute ago was likely sent by something that set the date by hand.
What the top 1,000 websites actually publish
A domain only protects you from forgery if its owner publishes SPF and DMARC records and sets the DMARC policy to reject or quarantine. So we checked.
On 23 October 2026 we took the top 1,000 sites from the Tranco list (list ID 56Z8N, created 22 October 2026, which combines Chrome usage, Cloudflare Radar, Cisco Umbrella, Majestic and Farsight data). For each domain we looked up the _dmarc TXT record, the SPF TXT record and the MX records through Cloudflare's public resolver. Two domains returned lookup errors; everything else is below.
DMARC and SPF by the numbers
| Top 100 | Top 1,000 | Top 1,000 that receive email | Top 1,000 with no mail service | |
|---|---|---|---|---|
| Domains | 100 | 1,000 | 684 | 316 |
| Publish any DMARC record | 76.0% | 72.2% | 89.2% | 35.4% |
| p=reject | 51.0% | 43.3% | 50.3% | 28.2% |
| p=quarantine | 13.0% | 17.0% | 24.1% | 1.6% |
| p=none (monitor only) | 12.0% | 11.8% | 14.8% | 5.4% |
| No DMARC record | 24.0% | 27.8% | 10.8% | 64.6% |
| Enforced (reject or quarantine at 100%) | 64.0% | 59.3% | 73.2% | 29.1% |
| Publish an SPF record | 82.0% | 75.4% | 93.9% | 35.4% |
| SPF ends in -all (hard fail) | 44.0% | 43.5% | 50.1% | 29.1% |
| SPF ends in ~all (soft fail) | 25.0% | 26.7% | 37.3% | 3.8% |
"Receive email" means the domain has MX records that are not a null MX (a record that says "this domain accepts no mail"). The "no mail service" group is mostly infrastructure domains such as content delivery networks and DNS providers. Many of those never send email, which explains why so many skip DMARC, though publishing p=reject on a domain that never sends mail is still the safer choice.
What stands out
About one in four top sites still does not enforce DMARC. Of the 684 top domains that receive email, 74 have no DMARC record and 101 are set to p=none. Combined, that is 25.6% of them where a forged message using their exact address can still reach an inbox if the receiver follows the domain's own instructions.
Microsoft's consumer mail domains are among them. live.com publishes v=DMARC1; p=none; sp=quarantine, and so do outlook.com and msn.com. Microsoft's corporate domain, microsoft.com, uses p=reject. Microsoft has its own extra checks inside Outlook, but other providers reading these records are told not to block failures.
The biggest brands mostly lock it down. google.com, microsoft.com, paypal.com, netflix.com, yahoo.com, linkedin.com, x.com and openai.com all publish p=reject. apple.com, amazon.com and github.com use p=quarantine, which sends failures to spam.
Nobody uses +all. Not one of the 1,000 domains had an SPF record ending in +all, which would allow any server in the world to send as them. Three domains (hichina.com, indiatimes.com and warnerbros.com) published two separate SPF records, which the SPF standard treats as an error, so receivers may ignore both.
Reporting is common. 67.1% of all top 1,000 domains, and 83.5% of those that receive email, ask for DMARC aggregate reports (rua=). Those reports are how a domain owner finds out who is sending mail in their name.
How to check any domain yourself
You do not need special software. Our DNS lookup tool shows TXT records. Look up:
_dmarc.yourwebsite.comfor the DMARC record. You want to seep=rejectorp=quarantine.yourwebsite.comfor TXT records starting withv=spf1. There should be exactly one, ending in-allor~all.
From a terminal, the same checks are:
nslookup -type=TXT _dmarc.yourwebsite.com
dig TXT yourwebsite.com +short
If you own a domain and the DMARC record is missing, start with v=DMARC1; p=none; rua=mailto:[email protected], read the reports for a few weeks, make sure every real sender passes, then move to p=quarantine and finally p=reject.
The bottom line
An email header tells you where a message really came from if you read it in the right direction: bottom up, stopping at the first server your own provider added. The Authentication-Results line then tells you whether the domain owner authorised that server. In our check of the top 1,000 websites, 72.2% publish DMARC but only 59.3% enforce it, and even Microsoft's live.com and outlook.com run at p=none. So a familiar sender name proves nothing. A dmarc=pass from a domain you recognise proves a lot. When in doubt, paste the header into our email header analyzer and look at those three checks first.
