dmarc

How to Read Email Headers to Check SPF, DKIM and DMARC

A practical walkthrough of email headers: how to open the raw source in Gmail, Outlook, and Apple Mail, then read the Received chain, Return-Path, and Authentication-Results to confirm SPF, DKIM, and DMARC or diagnose a failure.

Updated Jul 4, 20268 min read

Every email carries a block of metadata called headers that records where the message came from, every server it passed through, and whether it passed SPF, DKIM, and DMARC. To check authentication you open the raw source, find the Authentication-Results header, and read the spf=, dkim=, and dmarc= verdicts along with the domains they were checked against. This guide walks the full header top to bottom so you can confirm a message is legitimate or pinpoint exactly why a check failed.

Reads public DNS only. Nothing is stored unless you save the domain to an account.

How to view the raw source

The information you need lives in the raw source, not the rendered message. Each major client exposes it differently.

  • Gmail (web): Open the message, click the three vertical dots at the top right of the message pane, and choose Show original. Gmail displays the full headers plus a summary table showing SPF, DKIM, and DMARC as PASS or FAIL.
  • Outlook (new desktop and web): Open the message, click the three dots (...) near the reply buttons, then View and View message source. On classic Outlook desktop, open the message, go to File, then Properties, and read the Internet headers box.
  • Apple Mail (macOS): Select the message, then View, Message, and Raw Source (or press Command+Option+U). Note that iOS and iPadOS Mail cannot display raw source, so use a desktop client for diagnosis.

Once you have the raw text in front of you, start reading from the bottom up.

The Received chain

Received headers form a stamped travel log. Each server that handles the message adds its own Received line to the top, so the chain reads in reverse chronological order: the oldest hop (the originating server) sits at the bottom, and the server that delivered to your mailbox sits at the top.

A single hop looks like this:

Received: from mail.example.com (mail.example.com [192.0.2.10])
        by mx.google.com with ESMTPS id abc123
        for <you@yourdomain.com>; Tue, 04 Jul 2026 09:14:22 -0700 (PDT)

Read it as: the receiving server (by mx.google.com) accepted the message from a host that announced itself as mail.example.com and connected from IP 192.0.2.10. That bracketed IP is the one SPF and PTR checks evaluate, and it is the piece an attacker cannot fake. To trace a message's true origin, start at the bottom Received line and confirm the sending IP belongs to a network you expect. A legitimate transactional email should show a short, sensible chain; a long detour through unrelated hosts is worth a closer look. The reverse DNS name attached to that first IP matters for delivery, which is covered in what is a PTR record.

Return-Path and the envelope sender

The Return-Path header records the envelope sender, also called the bounce address or MAIL FROM. This is distinct from the From: address your recipient sees. SPF authenticates the envelope domain in Return-Path (the RFC 5321 MAIL FROM), not the visible From: domain (RFC 5322), which is why the two can differ and why alignment exists as a separate concept.

Return-Path: <bounces@mail.example.com>
From: "Example Billing" <billing@example.com>

Here SPF is checked against mail.example.com (the Return-Path domain), while the recipient sees example.com. If those two domains share an organizational domain, SPF is aligned for DMARC purposes. If a sending platform uses its own bounce domain with no relationship to your From: domain, SPF can pass while still failing DMARC alignment. For the full picture, see what is the Return-Path.

The Authentication-Results header

This is the header that answers the question directly. The receiving server writes it after running the checks, and you should trust only the copy added by the server that actually delivered to you (the topmost one from your own provider). A typical line reads:

Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of bounces@mail.example.com designates 192.0.2.10 as permitted sender) smtp.mailfrom=bounces@mail.example.com;
       dkim=pass header.i=@example.com header.s=selector1 header.b=Gw+yUxcC;
       dmarc=pass (p=REJECT sp=REJECT dis=none) header.from=example.com

Break it into three verdicts.

SPF

spf=pass means the sending IP (192.0.2.10) is authorized by the SPF record of the smtp.mailfrom domain. The smtp.mailfrom value tells you which domain was checked. A pass here only proves the envelope domain authorized the IP; it says nothing about the visible From: until DMARC applies alignment. If you see spf=permerror, the SPF record could not be evaluated, most often because it exceeded the limit of 10 DNS lookups. See SPF PermError vs TempError and fix SPF too many DNS lookups.

DKIM

dkim=pass means the cryptographic signature verified against the public key published in DNS. Two fields matter for alignment:

  • header.d (or header.i) is the signing domain. Here it is example.com.
  • header.s is the selector, selector1, which tells the receiver which key to fetch at selector1._domainkey.example.com. Modern setups use 2048-bit keys.

DKIM survives forwarding, unlike SPF, so it is often the check that keeps DMARC passing when a message is relayed.

DMARC

dmarc=pass is the verdict that governs the inbox. DMARC passes only when SPF or DKIM passes and the passing domain aligns with the visible From: domain (header.from=example.com). The policy in parentheses shows what the domain owner requested: p=none (monitor only), p=quarantine (send to spam), or p=reject (bounce). dis=none reports the disposition the receiver actually applied, which is no action because the message passed.

FieldWhat it tells you
smtp.mailfromDomain SPF checked (envelope sender)
header.d / header.sDKIM signing domain and selector
header.fromVisible From domain DMARC aligns against
p=Published DMARC policy
dis=Disposition the receiver applied

For a deeper reference on just this header, read how to read the Authentication-Results header. For the protocols themselves, see SPF, DKIM and DMARC explained.

Diagnosing a failure

When dmarc=fail appears, work through the results methodically.

  1. Check whether SPF or DKIM passed at all. If both say fail, the message was not authenticated by any method. Confirm the sending IP in the bottom Received line is in your SPF record and that the platform is signing with DKIM.
  2. If SPF passes but DMARC fails, suspect alignment. Compare smtp.mailfrom against header.from. Different organizational domains means SPF is not aligned. A dedicated bounce or custom Return-Path domain under your own name usually fixes this.
  3. If DKIM passes but DMARC fails, check the signing domain. Compare header.d against header.from. If a platform signs with its own domain, the signature is valid but not aligned. Adding a branded DKIM key on your domain resolves it. See fix DKIM alignment.
  4. If a message was forwarded, expect SPF to break. Forwarding rewrites the path but not the From:, so SPF fails against the forwarder's IP. DKIM should still carry the message through. This is covered in why email forwarding breaks SPF.

Alignment can be relaxed (a subdomain of the organizational domain counts as aligned) or strict (an exact match is required), which changes what counts as a pass. See DMARC relaxed vs strict alignment.

Why headers matter for deliverability

Reading headers is not only for forensics. The bulk-sender rules from Gmail, Yahoo, and Microsoft require that mail be authenticated, and the headers are where you prove it. Senders above 5,000 messages per day to Gmail must pass SPF and DKIM, publish DMARC on the From: domain, keep the spam complaint rate reported in Postmaster Tools under 0.3% (ideally under 0.1%), transmit over TLS, publish a valid forward-confirmed PTR record, and offer one-click unsubscribe per RFC 8058 on marketing mail. When you audit a sample of your own outbound mail, the Authentication-Results header is the fastest confirmation that every requirement is met. See Google and Yahoo sender requirements.

Frequently asked questions

Which Authentication-Results header should I trust?

Trust only the topmost one, written by your own receiving provider. Any Authentication-Results header lower in the chain was added by an upstream server and can be forged by a sender, so a receiver strips or ignores those. The header stamped by the server that delivered to your mailbox is the authoritative one.

Why does SPF pass but DMARC still fail?

SPF authenticates the Return-Path (envelope) domain, while DMARC requires that domain to align with the visible From: domain. If your sending platform uses its own bounce domain, SPF passes but does not align, so DMARC fails unless DKIM is aligned instead. Configuring a custom Return-Path under your own domain restores alignment.

Can I read headers on my phone?

You can view them in mobile web Gmail and in some third-party apps, but iOS and iPadOS Mail cannot display raw source. For reliable diagnosis, open the message in a desktop client such as Gmail on the web, Outlook, or Apple Mail on macOS where full raw source is available.

Do Received headers prove where an email came from?

The bracketed IP address in the bottom Received line is the most reliable origin signal, because it is recorded by the receiving server and cannot be faked by the sender. The announced hostnames can be spoofed, so always verify the connecting IP against the network you expect and against the SPF result.

Reading headers by hand is the right skill to have, but you do not need to do it for every message. Run your domain through the free SPFWise scanner to see your SPF, DKIM, and DMARC status at a glance, confirm alignment, and catch the misconfigurations that show up as failures in these headers before they cost you the inbox.

Check your own domain

Run a free scan and get your grade with the exact records to fix.

Scan a domain

Related guides

How to Read Email Headers for SPF, DKIM, DMARC