Technical

Understanding Email Headers: A Technical Guide

Email headers are the metadata that rides along with every message; they tell you where a mail came from, every server it touched, whether SPF, DKIM, and DMARC passed, and why a message got delayed, bounced, or flagged as spam.

Sohail HussainSohail Hussain(Updated: )11 min read

Email headers are the structured metadata attached to every message. They record where a mail came from, every server it passed through, which authentication checks passed, and which address should receive bounces. Learn to read them and you can diagnose almost any deliverability issue without guessing.

What are email headers?

Email headers are the lines at the top of a raw message that hold metadata: sender, recipient, date, subject, routing history, authentication results, and a long tail of optional fields. They sit above the body, separated by a single blank line. Most mail clients hide them; every mail server reads them.

RFC 5322, the Internet Message Format, splits headers into required and optional. The required list is short: an origination date (the Date: field) and an originator address (the From: field). Everything else, including To:, Subject:, Message-ID:, Received:, and every authentication header, is optional at the spec level. In practice, modern mail systems reject or spam-fold messages that skip the common ones, so "optional" is doing a lot of quiet work in that sentence. RFC 6854 later allowed group syntax in From: and Sender:, which is why you'll occasionally see From: undisclosed-recipients:; on bulk mail; legal, and a small red flag to some filters.

Every time an email hops from one server to the next, the receiving server prepends a new Received: line. The result is a stack reading newest to oldest, top to bottom, which combined with the authentication results tells you the exact path a message took. The transport underneath is SMTP, defined in RFC 5321. SMTP handles the envelope (the MAIL FROM and RCPT TO commands your server speaks); RFC 5322 handles the message riding inside. The difference between those two is the whole story when you're chasing a bounce problem.

Here's a full raw header on a message delivered to a Gmail inbox (fabricated, structurally accurate):

Return-Path: <bounces+847291-abcd@send.example.com>
Delivered-To: jordan@customerdomain.com
Received: by mx.google.com with SMTPS id 7c8d3e9f1a2b4c5d
        for <jordan@customerdomain.com>
        (Google Transport Security);
        Tue, 15 Apr 2026 09:14:22 -0700 (PDT)
Received: from mta-04.send.example.com (mta-04.send.example.com. [198.51.100.42])
        by mx.google.com with ESMTPS id g17-20020a17090a674b
        for <jordan@customerdomain.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384);
        Tue, 15 Apr 2026 09:14:22 -0700 (PDT)
Received-SPF: pass (google.com: domain of bounces+847291-abcd@send.example.com
        designates 198.51.100.42 as permitted sender)
        client-ip=198.51.100.42;
Authentication-Results: mx.google.com;
       dkim=pass header.i=@example.com header.s=mailneo202604 header.b=K9x3nQl2;
       spf=pass (google.com: domain of bounces+847291-abcd@send.example.com
            designates 198.51.100.42 as permitted sender)
            smtp.mailfrom=bounces+847291-abcd@send.example.com;
       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=example.com; s=mailneo202604;
        h=from:to:subject:date:message-id:list-unsubscribe;
        bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
        b=K9x3nQl2...signature...Q==
Message-ID: <20260415161422.847291.abcd@send.example.com>
Date: Tue, 15 Apr 2026 16:14:22 +0000
From: "Avery at Example" <hello@example.com>
Reply-To: support@example.com
To: jordan@customerdomain.com
Subject: Your April shipment is on the way
List-Unsubscribe: <https://click.example.com/u/abc123>, <mailto:unsub+abc123@send.example.com>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="==_boundary_847291=="
X-Mailneo-Campaign-ID: cmp_01HZAE6W9Y7TQ2X
X-Mailneo-Subscriber-ID: sub_01HZA7MK3R

That's roughly 25 lines of metadata for what the recipient reads as a one-line greeting.

The four headers to read first

Start with Authentication-Results, the topmost Received: line, Return-Path, and From:. Those four answer most of the questions you will ever have about a single message: did auth pass, which IP handed it off, where will a bounce go, and what did the recipient actually see as the sender.

If the message looks fine but never landed, open the raw source and read in this order:

  1. Authentication-Results: did SPF, DKIM, and DMARC all pass?
  2. The topmost Received: line; which IP delivered to the final mailbox?
  3. Return-Path: does it match the d= domain in the DKIM signature?
  4. From:: is this the domain the recipient expects?
  5. Message-ID: unique, and does the domain match what you sent from?

From there the rest of the stack fills in context. A mismatch between Return-Path and From: isn't automatically wrong, since it's how ESPs handle bounces, but it is the single most common reason a DMARC alignment check fails silently.

Reading the Received chain

The Received: chain is a stamped log of every mail server that handled the message. It reads bottom-up: the oldest hop, usually the original submission, sits at the bottom, and the final delivery to the recipient's mailbox sits at the top.

Each line records the sending host, its IP address, the receiving host, the SMTP extensions used, a transport ID, and a timestamp. Four servers means four Received: lines, and subtracting timestamps shows you where time went. A gap of 40 seconds between hops is nothing. A gap of 40 minutes points at a retry queue, which usually means greylisting or a temporary rejection upstream.

One quick sanity check that catches real problems: does the IP in the bottom Received: line match what your SPF record allows? If it doesn't, either somebody sent mail claiming to be you or your SPF is out of date.

Paste a raw header into Mailneo's email header analyzer and it rebuilds the hop chain visually, with timing deltas flagged per hop. I use it daily; reading a seven-hop message with three time zones by eye is a fast way to misplace an hour.

Authentication-Results, field by field

Authentication-Results is the single most important header for modern deliverability. It records whether SPF, DKIM, and DMARC each passed, failed, or errored, and its syntax is standardized by RFC 8601. Every major mailbox provider writes one.

A clean pass looks like this:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@example.com header.s=mailneo202604 header.b=K9x3nQl2;
       spf=pass smtp.mailfrom=bounces+847291-abcd@send.example.com;
       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

Read three things. The method (dkim, spf, dmarc) and its result (pass, fail, neutral, softfail, temperror, permerror). The identifier that was checked (header.from, smtp.mailfrom, header.i, header.s), which tells you which domain and selector were used. And for DMARC, the policy (p=) alongside the disposition (dis=); a p=REJECT with dis=NONE means the policy is enforcement-grade but this message passed, so nothing was quarantined.

The failure combinations each point somewhere specific. SPF passes and DKIM fails: a forwarding issue, or a mailing list rewriting the body. DKIM passes and SPF fails: your MAIL FROM domain is out of alignment with your ESP's IPs. Both pass individually and DMARC still fails: an alignment problem, where the domain in From: matches neither the SPF nor the DKIM domain.

For a fuller walkthrough of each protocol, see our SPF vs DKIM vs DMARC comparison, plus the per-protocol guides on SPF, DKIM, and DMARC.

Return-Path vs From

Return-Path is the envelope sender, where bounces go, set by the SMTP MAIL FROM command. From: is the header sender, what the recipient sees in their inbox. They are frequently different, and that difference trips up almost every new sender.

Say you send through an ESP. The From: might be hello@yourcompany.com, so the recipient recognizes you. The Return-Path will typically be bounces+sub12345@send.esp-domain.com, so the ESP catches bounces and suppresses future sends to bad addresses; our bounce rates guide covers what it does with them. That split is standard practice, and it is also exactly how DMARC alignment fails when your DKIM signature is over the ESP's domain rather than yours.

The fix is to align the DKIM signature to your domain. Any decent ESP sets this up during onboarding. If you're seeing DMARC failures with SPF and DKIM both passing, check this first.

Viewing full headers in Gmail, Outlook, and Apple Mail

Every major client hides headers by default and every one has a three-click path to the raw source.

In Gmail on the web, open the message, click the three-dot menu at the top right of the message itself rather than the toolbar, and pick "Show original"; you get a new tab with auth results at the top and the raw message below. Google's support page covers the download option for a raw .eml too.

In Outlook on Windows, open the message in its own window, then File > Properties, and read the "Internet headers" box at the bottom. Microsoft's documentation covers Outlook for Mac and Outlook on the web, which differ slightly (on the web it's ... > View > View message source).

In Apple Mail, select the message, then View > Message > All Headers, or Raw Source for the whole thing. Thunderbird uses View > Message Source, per Mozilla's support docs.

What you can diagnose from headers

Most of the deliverability problems that reach support come down to five patterns, and all five are visible in the headers.

Spoofing looks like a message that appears to come from your domain, with SPF failing and a Received: line originating from an IP you don't control. DMARC at p=reject blocks this at the provider level, which is the entire argument for enforcement.

Broken SPF after a vendor change is the most common self-inflicted one. The topmost Received: line shows a new IP, your SPF record doesn't include it yet, and Authentication-Results reports spf=fail or softfail. The fix is a DNS update.

DKIM body-rewrite failures happen when a mailing list or gateway alters the body and the signature stops validating. Authentication-Results shows dkim=fail with a bodyhash reason. Your options here are narrower; ARC (Authenticated Received Chain) helps, as do relaxed canonicalization choices.

Delayed delivery shows up as Received: timestamps jumping by minutes or hours between hops, usually greylisting or a queued retry on the sending side.

Missing List-Unsubscribe is the newest headache. Google and Yahoo's bulk-sender rules require one-click unsubscribe on marketing mail above 5,000 messages a day, per Google's sender guidelines. The spec is RFC 8058, and the header must include both List-Unsubscribe: and List-Unsubscribe-Post: List-Unsubscribe=One-Click. Miss either and Gmail quietly spam-folders the campaign.

One note while you're in there: anything starting with X- is nonstandard, added by ESPs for their own tracking. Those headers don't affect delivery; they trace a message back to a campaign or subscriber, which is useful in a support ticket and irrelevant to auth.

Header reference

HeaderWhat it meansRequired by RFC 5322?
FromThe author of the message; what the recipient sees as the sender.Yes
ToThe primary recipient. Can hold multiple addresses.No (but effectively always present)
SubjectFree-text subject line shown in the inbox list.No
DateWhen the message was composed, in RFC 5322 date format.Yes
Message-IDA globally unique identifier for the message; format is <local@domain>.No (but essential for threading and deduplication)
ReceivedOne line per server hop, stacked in reverse chronological order.No (added by transport)
Return-PathThe envelope sender; where bounces go. Set by the final MTA.No (added on delivery)
Reply-ToWhere replies should go if different from From.No
DKIM-SignatureThe cryptographic signature; includes d= domain and s= selector.No (but required for modern deliverability)
Authentication-ResultsResults of SPF, DKIM, and DMARC checks; syntax from RFC 8601.No (added by receiving server)
List-UnsubscribeOne-click unsubscribe URL and/or mailto:. Required for bulk senders.No (but required by Gmail/Yahoo bulk rules)

One field deserves a closer look. Message-ID takes the form <20260415161422.847291.abcd@send.example.com>; the left-hand side must be unique per message, and most ESPs build it from a timestamp, a random string, and a campaign ID. The right-hand side is a fully qualified domain, usually the sending MTA's hostname. RFC 5322 section 3.6.4 calls for a world-unique value, which in practice means a UUID or a high-resolution timestamp plus a random suffix. Reusing a Message-ID across two messages breaks threading in Gmail, and seeing <abc@localhost> in production mail means somebody's sending server was never configured properly.

Forgery and when to bother reading headers

Can email headers be forged?

The visible parts (From:, Subject:, even Received: lines) can be forged by anyone with an SMTP client. The authentication headers are what actually prove origin: the DKIM-Signature because it is cryptographic, and the Authentication-Results added by a trusted receiving server because it reflects that server's own checks rather than the sender's claims. Our email authentication glossary entry has the short version.

Do I need to inspect headers for every campaign?

No. Headers are a debugging tool, not a routine one. Pull them when something is wrong: a spike in spam complaints, a mysterious bounce, a DMARC aggregate report showing failures, a customer swearing they never received a message you can see was delivered. For the routine monitoring that tells you when to go looking, see the email deliverability guide.

email-headerstechnicaltroubleshootingdeliverabilityemail-authentication
Share this article
Sohail Hussain

Sohail Hussain

Founder & CEO at Mailneo

Building Mailneo — AI-powered email marketing for growing businesses.

Ready to supercharge your email marketing?

Start sending smarter emails with AI-powered campaigns. No credit card required.

Get Started Free