Resources / Guide
Email Headers and the SMTP Envelope, Explained
A message has two layers most people conflate: the SMTP envelope that moves it, and the RFC 5322 header block a person reads. This guide walks through both, every header that matters for deliverability and authentication, and how to read a full raw header set top-down to find a message's origin.
Last checked: June 22, 2026
An email is two things at once, and most confusion about bounces, authentication, and “why does the From: say one thing and the headers say another” comes from collapsing them into one. The envelope is what the two mail servers say to each other during the SMTP conversation - it routes the message and is thrown away on delivery. The message is the RFC 5322 header block plus body that travels inside the envelope - it is what a person eventually reads. They can carry completely different addresses, and that gap is by design.
This page walks through both layers, then through every header that matters for deliverability and authentication, with real examples, and closes with a full annotated raw-header set you can use as a map.
The 60-second version
- The envelope (RFC 5321) carries
MAIL FROM(the return path, for bounces) andRCPT TO(the actual recipient). Neither has to match anything in the visible headers. - The message (RFC 5322) carries
From:,To:,Subject:, and the rest - the header block a person sees. MAIL FROMbecomes theReturn-Path:the receiving server stamps on the delivered message;RCPT TOis where it actually went, regardless ofTo:.- SPF checks the envelope
MAIL FROM; DKIM signs the message; DMARC ties a passing identifier back to the visibleFrom:(see the authentication overview). Received:lines are a stack: the newest is at the top, the origin at the bottom. Read down to find where a message came from.- Headers like
Authentication-Results:(RFC 8601) record what the receiver decided; treat them as the receiver’s notes, not the sender’s claims.
Two layers: envelope vs message
When MTA A delivers to MTA B, the SMTP transaction looks roughly like this (covered in detail in reading SMTP replies):
MAIL FROM:<bounce-7f3a@mail.shop.example> <- the envelope sender (return path)
RCPT TO:<alice@example.net> <- the envelope recipient
DATA
From: Shop Receipts <receipts@shop.example> <- the message header a person reads
To: "Alice" <alice@example.net>
Subject: Your order #10428
...
The envelope MAIL FROM (bounce-7f3a@mail.shop.example) and the header From: (receipts@shop.example) are different on purpose: bounces should go to an automated mailbox, not to the human-facing address. RFC 5321 calls the envelope sender the reverse-path and the recipient the forward-path, and it is explicit that these envelope addresses drive delivery and bounce return, while the header fields are the message’s own content.
Two consequences worth internalizing:
RCPT TOis the real recipient, notTo:. A message can be delivered to an address that never appears inTo:orCc:(everyBcc:recipient, every alias, every mailing-list member). TheTo:header is author-supplied display text;RCPT TOis where the bytes were actually sent.- The envelope is ephemeral. Once delivered, the only durable trace of the envelope sender is the
Return-Path:header the final MTA writes. Everything else about the SMTP conversation lives (if anywhere) in theReceived:lines.
The null reverse-path
The envelope sender can be empty: MAIL FROM:<>. RFC 5321 reserves this null reverse-path for messages that must never themselves bounce - chiefly Delivery Status Notifications (bounce messages) and auto-replies. RFC 3834 recommends a MAIL FROM of <> for automatic responses precisely so a bounce of a bounce cannot start a loop. If you see Return-Path: <> on a delivered message, it was sent with a null envelope sender, which is the correct signature of a system-generated report.
Return-Path (RFC 5321, RFC 5322)
Return-Path: is the header form of the envelope MAIL FROM. RFC 5322 defines it as a trace field whose value is “a pair of angle brackets that enclose an optional addr-spec” - so a normal one looks like Return-Path: <bounce-7f3a@mail.shop.example> and a null one looks like Return-Path: <>. RFC 5321 says the receiving MTA adds it at final delivery, copying the reverse-path from the transaction.
Why it matters for senders:
- It is the address bounces and DSNs are sent to. If you want machine-readable bounce processing (and you do - see bounces and DSN parsing), the envelope sender must point at a mailbox you parse, not at a human inbox.
- For DMARC, SPF is evaluated against the
MAIL FROMdomain (the futureReturn-Pathdomain), and that domain must align with theFrom:domain to help DMARC pass. AReturn-Pathon your ESP’s bounce domain that does not share yourFrom:Organizational Domain is exactly why “SPF: pass” can still mean “DMARC: fail” (see the SPF deep dive).
The originator fields: From, Sender, Reply-To
These are the RFC 5322 “originator fields” (§3.6.2), and they answer three different questions.
| Field | ABNF | Answers |
|---|---|---|
From: | mailbox-list | Who wrote the message (the author) |
Sender: | single mailbox | Who actually sent it, if not the author |
Reply-To: | address-list | Where replies should go, if not From: |
RFC 5322 §3.6.2 sets the rule most senders get wrong: if From: contains more than one mailbox, a Sender: field naming a single mailbox MUST appear. The classic illustration is an assistant sending for an executive - the executive is in From:, the assistant in Sender:. If author and transmitter are the same single mailbox, Sender: SHOULD be omitted. And in the absence of Reply-To:, replies default to From:.
The From: field is special because it is the identity DMARC authenticates and the one almost every mail client displays. RFC 5322 is blunt that From: “SHOULD NOT contain any mailbox that does not belong to the author(s) of the message” - which is the standards-level statement of why From: spoofing is the problem DMARC exists to close (see DMARC in 2026).
Group syntax in From/Sender (RFC 6854)
Original RFC 5322 forbade “group” address syntax in From: and Sender:. RFC 6854 (which updates 5322) relaxes that for limited use, mainly so an automated system can present an unrepliable origin:
From: Automated System:;
That empty group is a valid From: under RFC 6854. A named group is also allowed:
From: Managing Partners:ben@example.com,carol@example.com;
Sender: dave@example.com
But RFC 6854 explicitly marks this as Limited Use and says user agents “SHOULD NOT permit the use of groups in those fields in outgoing messages,” because much software assumes From:/Sender: are replyable single mailboxes. It also warns that group syntax with no real address can break protocols that match From: to a verified domain - i.e., it can hurt authentication and deliverability. For ordinary sending: use a single, real mailbox in From:.
Destination fields: To, Cc, Bcc
RFC 5322 §3.6.3 defines all three as the same form (a field name plus an address-list); they differ only in use:
To:- the primary recipients.Cc:(“carbon copy”) - recipients who get a copy but aren’t the message’s main target.Bcc:(“blind carbon copy”) - recipients hidden from the others. RFC 5322 describes the handling: theBcc:line is normally removed before the copies toTo:/Cc:recipients are sent, and aBcc:field may even contain no addresses (signaling that blind copies went to someone).
The deliverability point bears repeating: these are display/author conveniences. The recipients who actually receive the message are the RCPT TO addresses from the envelope, which include every Bcc: target and may include none of the visible To:.
Subject and Date
Subject:is an unstructured informational field (RFC 5322 §3.6.5). Non-ASCII subjects must be encoded per RFC 2047 (below).Date:(RFC 5322 §3.6.1) is the origination date. Its format is fixed by §3.3:[day-of-week ","] day month year hour:minute[:second] zone, for exampleTue, 23 Jun 2026 09:41:07 +0000. The zone is a four-digit offset from UTC;+0000is UTC, and-0000specifically means “generated where the local zone is unknown.” A malformed or missingDate:is a common, cheap spam signal, so emit a correct RFC 5322 date.
Message-ID, In-Reply-To, References (threading)
These are the RFC 5322 “identification fields” (§3.6.4).
Message-ID:is a single globally unique identifier for the message, in the form<unique@domain>(an addr-spec-shaped token in angle brackets). A message “SHOULD have” one. The domain part should be one you control, and the left-hand side should be unique per message.In-Reply-To:contains theMessage-IDof the message being replied to.References:contains the chain ofMessage-IDs up the thread.
RFC 5322 §3.6.4 specifies exactly how a reply builds these: In-Reply-To: gets the parent’s Message-ID; References: is the parent’s References: (if any) followed by the parent’s Message-ID. That is how mail clients reconstruct conversation threads. For senders, two practical notes: keep Message-ID genuinely unique (duplicates can collapse distinct messages in a client), and use a domain you own (some filters look askance at Message-ID domains unrelated to the sender).
MIME headers (RFC 2045, RFC 2047)
Plain RFC 5322 bodies are US-ASCII text. MIME (RFC 2045 and its companions) is how everything else - HTML, attachments, non-ASCII text, alternative parts - travels.
MIME-Version: 1.0declares the message uses MIME. RFC 2045 §4 requires it at the top level of a MIME message (it is not required on each body part).Content-Type:names the media type. The default, absent any header, istext/plain; charset=us-ascii(RFC 2045 §5.2). A typical HTML email with a text fallback is amultipart/alternative, and RFC 2045 §5.1 requires aboundaryparameter for anymultiparttype:
Content-Type: multipart/alternative; boundary="b1_4f8e2a"
Content-Transfer-Encoding:says how the body bytes are encoded for transport. RFC 2045 §6.1 enumerates the mechanisms:7bit(the default),8bit,binary,quoted-printable, andbase64.quoted-printableis used for mostly-ASCII text with a few high-bit characters;base64for binary attachments.
Encoded-words for non-ASCII headers (RFC 2047)
Header fields are ASCII, so a non-ASCII Subject: or display name is wrapped in an RFC 2047 “encoded-word”: =?charset?encoding?encoded-text?=. The encoding is B (base64) or Q (a quoted-printable variant), both case-independent, and a single encoded-word “may not be more than 75 characters long” (RFC 2047 §2). For example, a subject of “Réservation confirmée” might appear as:
Subject: =?UTF-8?Q?R=C3=A9servation_confirm=C3=A9e?=
A mail client reverses the encoding for display. If you see raw =?...?= in an inbox, a client failed to decode it - usually a malformed encoded-word.
The trace fields: reading Received top-down
Received: and Return-Path: are RFC 5322’s “trace fields” (§3.6.7). Each MTA that handles a message prepends a Received: line, so they accumulate as a stack: the most recent hop is at the top, the origin is at the bottom. RFC 5321 §4.4 defines what each line records (the from host, the by host, with the protocol, an id, an optional for recipient, and a timestamp).
To trace a message’s true origin, read the Received: lines from the bottom up:
Received: from mx.example.net (mx.example.net [203.0.113.9])
by mail.bigprovider.example with ESMTPS id abc123
for <alice@example.net>; Tue, 23 Jun 2026 09:41:10 +0000 <- 3rd hop (delivery)
Received: from relay.shop.example (relay.shop.example [198.51.100.7])
by mx.example.net with ESMTPS id def456;
Tue, 23 Jun 2026 09:41:08 +0000 <- 2nd hop
Received: from app-07.internal (localhost [127.0.0.1])
by relay.shop.example with ESMTP id ghi789;
Tue, 23 Jun 2026 09:41:07 +0000 <- 1st hop (origin)
The bottom line is where the message entered the mail system (app-07.internal via relay.shop.example); the top is the final delivery. Caveats from operators: only Received: lines added by systems you trust are trustworthy - a spammer can forge lines below the first hop you control, so the reliable part of the trace begins at the first MTA you operate and goes up. The for <...> clause can disclose the envelope recipient but, as RFC 9228 notes, it “is not used reliably, and its semantics are not thoroughly defined.”
Authentication-Results (RFC 8601)
When a receiver runs SPF, DKIM, and DMARC, it records the verdicts in an Authentication-Results: header (RFC 8601) so downstream agents (and you, reading a copy) can see them without re-checking. The syntax is an authserv-id (the checking host’s name) followed by method/result pairs and the properties evaluated:
Authentication-Results: mx.example.net;
spf=pass smtp.mailfrom=mail.shop.example;
dkim=pass header.d=shop.example;
dmarc=pass header.from=shop.example
Reading it:
spf=pass smtp.mailfrom=...- SPF passed for the envelopeMAIL FROMdomain. RFC 8601 §2.7.2 specifies thesmtpptype withmailfrom(orhelo) here.dkim=pass header.d=...- a DKIM signature validated for that signing domain (thed=value).dmarc=pass header.from=...- DMARC passed, evaluated against theFrom:domain.- A bare
; nonemeans no authentication was performed, not that it failed (RFC 8601 §2.2).
Two honesty notes. First, Authentication-Results: is only meaningful when added by a host you trust; anyone can write the header, so receivers strip pre-existing ones at their trust boundary. Second, RFC 8601 supersedes the older single-purpose header Received-SPF (defined in RFC 7208 §9.1) - you will still see Received-SPF: from some MTAs, but Authentication-Results: is the general mechanism.
DKIM-Signature (RFC 6376)
The DKIM-Signature: header carries the cryptographic signature DKIM adds. Its tags are defined in RFC 6376 §3.5; the ones to recognize when reading a header:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=shop.example; s=mail2026; t=1750671667;
h=from:to:subject:date:message-id;
bh=...; b=...
d=is the signing domain (the identity DKIM asserts; this is what DMARC aligns against).s=is the selector; combined withd=, the verifier fetches the public key froms._domainkey.din DNS.h=is the list of signed headers - changing any of these in transit breaks the signature. Note whetherfromis included (it must be, for DMARC purposes).b=is the signature;bh=is the body hash. The full mechanics are in the DKIM deep dive.
The reason DKIM survives some forwarding where SPF cannot is exactly this: it signs message content rather than checking the connecting IP (see forwarding and redirection).
List, Auto-Submitted, and Delivered-To headers
A few more headers carry operational meaning:
List-*(RFC 2369) -List-Unsubscribe,List-Help,List-Post, etc. RFC 2369 says these “MUST only be generated by mailing lists, not end users,” and there must be at most one of each.List-Unsubscribe(paired with one-click per RFC 8058) is the load-bearing one for bulk senders; see suppression and consent.Auto-Submitted(RFC 3834) - labels machine-generated mail:auto-generatedfor periodic/cron output,auto-repliedfor automatic replies. A responder seeing any value other thannoSHOULD NOT reply, which is the primary loop-prevention mechanism for vacation/auto-reply systems. At most oneAuto-Submittedfield per message.Delivered-To(RFC 9228) - records the address used at each delivery, prepended like a trace field (newest on top). RFC 9228 is Experimental, but the header is widely used for loop detection: “the presence of an existing Delivered-To: header field, for the same address, typically indicates a handling loop.” It is most visible in forwarding and alias chains, where a sequence ofDelivered-To:lines maps the path a message took.
A full annotated example
Here is a realistic header set, top to bottom, for a receipt that was sent by a shop, relayed, and delivered. Read the Received: block from the bottom up to find the origin.
Return-Path: <bounce-7f3a@mail.shop.example>
Delivered-To: alice@example.net
Received: from mx.example.net (mx.example.net [203.0.113.9])
by store.example.net with LMTP id xyz999
for <alice@example.net>; Tue, 23 Jun 2026 09:41:11 +0000
Received: from relay.shop.example (relay.shop.example [198.51.100.7])
by mx.example.net with ESMTPS id def456
for <alice@example.net>; Tue, 23 Jun 2026 09:41:08 +0000
Received: from app-07.internal (localhost [127.0.0.1])
by relay.shop.example with ESMTP id ghi789;
Tue, 23 Jun 2026 09:41:07 +0000
Authentication-Results: mx.example.net;
spf=pass smtp.mailfrom=mail.shop.example;
dkim=pass header.d=shop.example;
dmarc=pass header.from=shop.example
Received-SPF: pass (mx.example.net: domain of mail.shop.example
designates 198.51.100.7 as permitted sender)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=shop.example; s=mail2026; t=1750671667;
h=from:to:subject:date:message-id; bh=...; b=...
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="b1_4f8e2a"
From: Shop Receipts <receipts@shop.example>
To: "Alice" <alice@example.net>
Subject: Your order #10428
Date: Tue, 23 Jun 2026 09:41:07 +0000
Message-ID: <10428.1750671667@shop.example>
List-Unsubscribe: <https://shop.example/u/opaque123>,
<mailto:unsub@shop.example?subject=stop>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
How to read it:
Return-Path: <bounce-7f3a@mail.shop.example>- bounces go to the shop’s automated mailbox, not toreceipts@. The envelope sender’s domain (mail.shop.example) shares theFrom:Organizational Domain (shop.example), so it is SPF-aligned for DMARC.Delivered-To: alice@example.net- the address the final store actually delivered to.Received:block - read bottom-up:app-07.internalproduced it,relay.shop.examplerelayed it out,mx.example.netaccepted it,store.example.netdelivered it locally over LMTP.Authentication-Results:- the receiver’s verdicts: SPF, DKIM, and DMARC all passed, with DMARC evaluated againstheader.from=shop.example.DKIM-Signature:- signed byshop.example(aligned withFrom:), selectormail2026, coveringfromamong other headers.From:/To:/Subject:/Date:/Message-ID:- the human-facing message content and its unique identifier.List-Unsubscribe+List-Unsubscribe-Post- one-click unsubscribe is wired up (and must be inside the DKIMh=to function per RFC 8058).
Common confusion
- “The
From:and the envelope sender must match.” No. They routinely differ; bounces go to the envelope sender, humans seeFrom:. DMARC only requires alignment between theFrom:domain and a passing SPF (MAIL FROM) or DKIM (d=) identifier - not header equality. - “
To:is who got the mail.” Not necessarily.RCPT TOis.Bcc:recipients and aliases never appear inTo:. - “The top
Received:is the sender.” Backwards. The top is the most recent hop (usually your own delivery); the origin is at the bottom, and only the hops you control are trustworthy. - “
Authentication-Results: ...; nonemeans it failed.” It means no check was run, not that one failed. - “
Return-Path:is something the sender writes.” The receiving MTA writes it at delivery from the envelopeMAIL FROM; you influence it by choosing the envelope sender, not by adding the header yourself.
What Egressif does
We treat the envelope and the header block as the two distinct levers they are. The envelope MAIL FROM points at a return-path domain that is aligned with your visible From: so SPF contributes to DMARC, and at a mailbox we actually parse so bounces and DSNs feed suppression instead of disappearing. We DKIM-sign with the From: and the unsubscribe headers inside the h= list, emit correct RFC 5322 dates and unique Message-IDs, set MIME and transfer-encoding correctly so non-ASCII content renders, and keep the From: a single real mailbox. When something is misdelivered or flagged, the Received: trace and Authentication-Results: are where we start - read bottom-up, from the first hop we control. None of this guarantees the inbox; it removes the structural reasons a well-formed message gets misjudged.
Related references
- Email Deliverability Best Practices - The Playbook One deep, skimmable playbook for legitimate bulk and transactional senders, synthesized from the standards bodies (M3AAWG, IETF), the mailbox providers (Gmail, Yahoo, Microsoft, Apple, Orange, GMX), the major blocklist (Spamhaus), and the leading ESP documentation. Every section is a checklist that links out to our deep pages, and we use only the thresholds providers actually publish - no invented warmup curves, no universal score myths.
- Email Forwarding and Redirection, Explained Forwarding is where authentication goes to die: SPF breaks the moment the relaying IP changes, and list software breaks DKIM by editing the message. This guide explains exactly what breaks and why, the mechanisms involved - Sieve redirect, aliases, SRS, ARC - and how to build a forwarding product that does the least harm.
- How to Report Email Abuse: Spam, Phishing, Spoofing A practical, standards-based guide to reporting email abuse. How to tell what counts as abuse, trace the real source from the headers, find the responsible network's abuse contact, and route the report to the place that can act on it - the sending provider, your mailbox provider's "report spam" button, APWG and government phishing channels, or a blocklist.
Tell us what you run today.
Domains, rough volume, current providers, and what hurts. You will get a straight answer on fit, and a real number, in one conversation.