What email headers can and can’t tell you
Headers show what your mail service recorded when the message arrived: dmarc=pass in its Authentication-Results means SPF or DKIM passed for the From domain. They can’t prove who wrote the message. A lookalike such as micros0ft.com passes DMARC for itself, so read the domain letter by letter.
Anyone can write any From address, name and Reply-To, and add fake Received lines and fake results lower down. Only the lines the receiving side adds on top, with its own Received line, are out of the sender’s reach. The analyser finds the line where the message came in. For Gmail, Microsoft 365, Yahoo, Fastmail, iCloud, Proton and Zoho, whose layouts it knows, it reads the results as that service’s record (“Gmail recorded”). For any other server, only results above the line where the message came in count. Passes written below it are listed but never trusted, since the sender could have written them, so honest mail on such servers (many Exim and Postfix setups) shows amber. Mail handed in on the server itself is called inside only when the From is the server’s own domain. It never says an email is genuine.
A label only means something if you copied the headers from your own mailbox, from the very top. A copy someone sends you can be edited, and an email attached to another has headers written by whoever attached it, so its results are not shown as anyone’s. A DMARC failure counts from any line above the one the message came in by, and from any line that names the From domain, since a forger has no reason to fake one. ARC records count only when the receiver says it trusted them. A failed DMARC on a real message usually means a mailing list or forwarder changed it; the ARC lines then show what the forwarder saw.
SPF, DKIM and DMARC results
| spf=pass | The server that delivered it may send for the envelope sender's domain (Return-Path). Says nothing about the From on its own |
|---|---|
| spf=softfail | Not on the domain's list; the domain asks receivers to accept but mark it (~all) |
| dkim=pass | A signature by the domain in d= matched the headers it names and the body it covers |
| dkim=fail | Changed on the way (a list or forwarder) or forged |
| dmarc=pass | SPF or DKIM passed for the From address's own domain |
| dmarc=fail | Neither did. With p=quarantine or p=reject the receiver junks or refuses it |
| dmarc=bestguesspass | Microsoft: the domain has no DMARC record, but it would have passed |
| arc=pass | A forwarder sealed what it saw, and the seal checks out |
| compauth=pass | Microsoft's own judgement of the sender, from all of the above. The reason code says why |
Reading the Received lines
Every server adds a Received line on top, so read them from the bottom up: from is the server that handed the message over, by the one that took it, with how (ESMTPS means encrypted, ESMTPSA a logged-in sender) and the date after the semicolon when. The time between two lines is how long that hop took. A hop that seems to arrive before the one before it has a server with its clock wrong, not a message that travelled back in time.
Lines below the one where the message reached the recipient's provider were written by the sender's side and can be made up. The first public address among them is usually the sender's mail server, sometimes the sender's own internet connection.
Microsoft 365 spam headers
| Field | Meaning |
|---|---|
| SCL | Spam confidence: −1 skipped, 0 and 1 not spam, 5 and 6 spam, 9 high confidence spam |
| SFV | The filter's verdict: NSPM not spam, SPM spam, SFE safe sender, BLK blocked sender, SKA, SKN and SKI skipped |
| CAT | The policy that acted: SPOOF, PHSH and HPHSH (phishing), SPM and HSPM (spam), BULK, MALW, DIMP and UIMP (impersonation) |
| BCL | Bulk complaint level in X-Microsoft-Antispam: 0 not bulk, up to 9 for bulk mail with many complaints |
| CIP, CTRY, PTR | The connecting server's address, its country and its name |
| compauth | In Authentication-Results: Microsoft's own pass or fail, with a reason code (000 is a DMARC failure, 130 an ARC pass) |
Questions
No. It shows what the receiving server recorded when the message arrived and warns about what looks wrong. A pass means the From domain’s checks passed on arrival. It does not mean the domain is the one you think, or that the message is safe.
The sender can write any header, including fake Received lines and fake results further down. What the receiving server adds on top cannot be faked by the sender, but anyone who hands you a copy can edit it. That is why a result only means something in headers you copied from your own mailbox.
Usually a mailing list or forwarding rule changed the message (a subject tag, a footer), which breaks DKIM, and the forwarder’s server is not in the sender’s SPF. Or the sender uses a mail service it never added to its SPF or DKIM.
Only roughly. Big mail services like Gmail and Outlook.com do not show the sender’s own address, only their servers’. Look up the first public address to see whose network it is.
Mail forwarded to Gmail can show a DMARC failure even when Gmail accepted the forwarder’s ARC record. Mail that passes through a filtering service such as Mimecast before Microsoft 365 can show a DMARC failure on genuine mail. Postfix setups that write DKIM and DMARC results as separate lines under their Received line show amber. DKIM, ARC and SPF results are only read from the headers, never checked again.
No. They are read on your device. Check now asks public DNS for the From domain’s SPF and DMARC, the DKIM keys its signatures name, and the delivering server’s public address on blacklists, and nothing else. Names that exist only inside a network and private addresses are never sent.