---
title: "Email header analyzer: trace delivery, SPF, DKIM and DMARC"
description: "Paste email headers to see every hop a message took, the delay at each one, and its SPF, DKIM and DMARC results. Free, and it runs in your browser, so your headers stay private."
url: "https://nextmail.sh/tools/email-header-analyzer"
---

Tools

# Email header analyzer, every hop and every verdict.

Paste the headers of any email to see each server it passed through, how long it waited at each one, and whether SPF, DKIM and DMARC passed. It all runs in your browser, so the headers never leave it.

Email headers

Read in your browser. Nothing is uploaded, logged or stored.

## How to analyze email headers

1. 01
   
   Copy the headers
   
   Open the message in your mail app and copy its full headers or its original source. The table further down shows where each app keeps them.
2. 02
   
   Paste them here
   
   Paste them into the box or open a saved .eml file, then select Analyze headers. They are read in your browser and sent nowhere.
3. 03
   
   Read the report
   
   Follow the route from the first server to the last, see where the message waited, and check whether SPF, DKIM and DMARC passed and lined up with the From address.

## How to read email headers

Every email carries a block of headers above the body. A few are written by the app that composed it, such as From, To, Subject, Date and Message-ID. The rest are added by the servers that handle the message on its way.

Each server that accepts the message adds a Received line at the very top, so the list reads in reverse. The bottom Received line is the first hop, closest to the sender, and the top one is the server that handed the message to your mailbox. Read them from the bottom up to retrace the route, and the timestamps show where the message waited.

The receiving server records its verdicts in Authentication-Results: whether the sending server was allowed by the domain’s SPF record, whether each DKIM signature verified, and whether the message passed DMARC for the domain in the From address. The top result was written by your own provider, so it is the one to trust.

Anything below the servers you trust can be forged. A sender can write fake Received lines and even a fake Authentication-Results header, but it cannot change what your provider added above them, which is why a reading always starts at the top.

Filters add headers of their own. Microsoft 365 writes a spam confidence level and a bulk complaint level, SpamAssassin writes a score, and mailing lists add unsubscribe headers. Those explain why a message landed in Junk, or why it offered a one-click unsubscribe.

## How to view full email headers

Every major mail app can show a message’s full headers or its original source, though the option is rarely where you would look first. Copy everything it shows and paste it above.

| Mail app | How to see the full headers |
| --- | --- |
| Gmail on the web | Open the message, select More (the three dots beside Reply) and choose Show original. Select Copy to clipboard, then paste it above. |
| Gmail app on a phone | The app cannot show headers. Open the message in Gmail on a computer, or in a mobile browser, and use Show original. |
| Outlook on the web and new Outlook | Open the message, select More actions (the three dots), then View and View message details. Copy the text in the window that opens. |
| Classic Outlook for Windows | Double-click the message to open it in its own window, then select File and Properties. The headers are in the Internet headers box. |
| Outlook for Mac | Right-click the message in the list and choose View Source. |
| Apple Mail on a Mac | Select the message, then choose View, Message and All Headers, or Raw Source to see everything. |
| Mail on iPhone and iPad | The app cannot show full headers. Open the message in your provider’s webmail or in Mail on a Mac. |
| Yahoo Mail | Open the message, select More (the three dots) and choose View raw message. |
| Thunderbird | Open the message and choose View, then Message Source. You can also press Ctrl+U, or Cmd+U on a Mac. |
| Proton Mail | Open the message, select More (the three dots) and choose View headers. |

- **Mail app**
  Gmail on the web
- **How to see the full headers**
  Open the message, select More (the three dots beside Reply) and choose Show original. Select Copy to clipboard, then paste it above.

- **Mail app**
  Gmail app on a phone
- **How to see the full headers**
  The app cannot show headers. Open the message in Gmail on a computer, or in a mobile browser, and use Show original.

- **Mail app**
  Outlook on the web and new Outlook
- **How to see the full headers**
  Open the message, select More actions (the three dots), then View and View message details. Copy the text in the window that opens.

- **Mail app**
  Classic Outlook for Windows
- **How to see the full headers**
  Double-click the message to open it in its own window, then select File and Properties. The headers are in the Internet headers box.

- **Mail app**
  Outlook for Mac
- **How to see the full headers**
  Right-click the message in the list and choose View Source.

- **Mail app**
  Apple Mail on a Mac
- **How to see the full headers**
  Select the message, then choose View, Message and All Headers, or Raw Source to see everything.

- **Mail app**
  Mail on iPhone and iPad
- **How to see the full headers**
  The app cannot show full headers. Open the message in your provider’s webmail or in Mail on a Mac.

- **Mail app**
  Yahoo Mail
- **How to see the full headers**
  Open the message, select More (the three dots) and choose View raw message.

- **Mail app**
  Thunderbird
- **How to see the full headers**
  Open the message and choose View, then Message Source. You can also press Ctrl+U, or Cmd+U on a Mac.

- **Mail app**
  Proton Mail
- **How to see the full headers**
  Open the message, select More (the three dots) and choose View headers.

## The headers that matter most

A message can carry dozens of headers. These are the ones worth reading first when you trace a delivery problem.

- **`Received` Every server on the way**
  Added by every server that accepted the message: where it came from, which server took it, how and when. The bottom one is the first hop.
- **`Authentication-Results` The receiving server**
  The receiving server’s verdicts on SPF, DKIM, DMARC and similar checks. Trust the top one, which your own provider wrote.
- **`DKIM-Signature` The signing domain**
  A cryptographic signature by the domain in d=. The public key that checks it is published at the selector in s=, under \_domainkey.
- **`Received-SPF` The receiving server**
  The SPF result a receiving server recorded, with the IP address it checked and the domain it checked it against.
- **`ARC-Seal` Forwarders and mailing lists**
  Seals one ARC set so a later server can tell whether the chain was changed. cv= says whether the earlier sets verified.
- **`Return-Path` The server that delivered it**
  The envelope sender, where bounces go. SPF is checked against this domain, which is often a bounce domain of the sending service.
- **`Message-ID` The sending app or server**
  A unique identifier the sending app or server gives the message. Replies refer to it.
- **`Delivered-To` The server that delivered it**
  The mailbox this copy was delivered to, added by the receiving system. Useful when you were in Bcc or on a list.
- **`List-Unsubscribe-Post` The bulk sender**
  Says the unsubscribe link accepts a one-click request (RFC 8058). Gmail and Yahoo require it from bulk senders.
- **`X-Forefront-Antispam-Report` Microsoft 365**
  Microsoft 365 filtering details: the connecting IP and country, the spam confidence level (SCL), the filter verdict (SFV) and the threat category (CAT).
- **`X-Spam-Status` SpamAssassin**
  SpamAssassin’s verdict: Yes or No, the score, the threshold and the rules that matched.

## Problems the headers reveal

Most delivery puzzles leave the same few traces in the headers. Here is what each looks like and what to do about it.

### SPF fails after forwarding

A forwarding server resends the message from its own address, so SPF compares the original domain’s record with an IP that is not in it and records spf=fail or softfail.

How to fix Rely on DKIM, which survives forwarding when the body is untouched, and ask the forwarder to use SRS or ARC. Make sure DMARC can pass on DKIM alone.

### DKIM fails with body hash did not verify

Something changed the body after it was signed: a mailing list footer, a security gateway rewriting links, or a disclaimer added on the way out.

How to fix Sign after the last change, or stop the change. For lists, use ARC so receivers can trust the earlier result. Relaxed canonicalization helps with whitespace, not with added text.

### DMARC fails although SPF and DKIM pass

SPF passed for your provider’s bounce domain and DKIM passed for your provider’s signing domain, but neither matches the domain in From, so nothing aligned.

How to fix Set up a custom return path on your own domain, and have the provider sign with your domain (d=yourdomain) using the DKIM records it gives you.

### A long wait at one hop

A gap of minutes between two Received lines usually means the receiving server deferred the first attempt, as greylisting does, or the sending server queued the message under load.

How to fix Usually nothing: the sender retried and the message went through. If it repeats, check the sending server’s queue and retry interval, and whether its IP is on a block list.

### Junk folder with a high SCL

Microsoft 365 writes an SCL of 5 or 6 for spam and 7 to 9 for high confidence spam, and the message is moved to Junk.

How to fix Make sure SPF, DKIM and DMARC pass and align, check the BCL for bulk complaints, and ask the recipient’s admin to report it as not junk or allow your domain.

### Timestamps that go backwards

A hop that seems to arrive before the previous one means a server’s clock or time zone is set wrong. The message was not delayed.

How to fix Nothing to fix on your side. If the server is yours, sync its clock with NTP and set its time zone correctly.

### No DKIM signature at all

Authentication-Results says dkim=none, or there is no DKIM-Signature header. The sending service is not signing mail for your domain.

How to fix Turn on DKIM in the sending service, publish the key it gives you under \_domainkey, and check it with the DKIM record checker.

### SPF soft fail (all)

spf=softfail means the sending IP is not in the domain’s SPF record, which ends in ~all, so receivers treat the message with suspicion instead of rejecting it.

How to fix Add the sending service to your SPF record with the include it documents, keep the record under 10 DNS lookups, and check it with the SPF record checker.

## Questions this raises

Send mail that passes these checks.

Add your domain to Nextmail and you get the SPF and DKIM records to publish, checked until they resolve, and mail signed with your own domain so DMARC can align.

[Set up a domain](https://nextmail.sh/signup.md)

[Deliverability checker](https://nextmail.sh/tools/deliverability.md)[SPF record checker](https://nextmail.sh/tools/spf-checker.md)[DKIM record checker](https://nextmail.sh/tools/dkim-checker.md)[DMARC record generator](https://nextmail.sh/tools/dmarc.md)[SPF, DKIM and DMARC, explained](https://nextmail.sh/blog/spf-dkim-dmarc-explained.md)[All tools](https://nextmail.sh/tools.md)
