egressif.

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.

SMTP ENVELOPERFC 5321 · routes, then discardedMAIL FROM: bounce@shop.examplereturn path - where bounces goRCPT TO: alice@example.netthe real recipientReturn-Path: bounce@shop.examplestamped by receiver at deliverySEPARATE LAYERSMESSAGE HEADERSRFC 5322 · what a person readsFrom: receipts@shop.exampleTo: alice@example.netSubject: Your order #10428Message-ID: 10428@shop.exampleDKIM-Signature: d=shop.exampleReceived: from relay.shop.example
Two separate layers: the SMTP envelope that routes the message and is discarded, and the message headers a person reads. They can carry different addresses by design.

The 60-second version

  • The envelope (RFC 5321) carries MAIL FROM (the return path, for bounces) and RCPT 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 FROM becomes the Return-Path: the receiving server stamps on the delivered message; RCPT TO is where it actually went, regardless of To:.
  • SPF checks the envelope MAIL FROM; DKIM signs the message; DMARC ties a passing identifier back to the visible From: (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 TO is the real recipient, not To:. A message can be delivered to an address that never appears in To: or Cc: (every Bcc: recipient, every alias, every mailing-list member). The To: header is author-supplied display text; RCPT TO is 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 the Received: 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 FROM domain (the future Return-Path domain), and that domain must align with the From: domain to help DMARC pass. A Return-Path on your ESP’s bounce domain that does not share your From: 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.

FieldABNFAnswers
From:mailbox-listWho wrote the message (the author)
Sender:single mailboxWho actually sent it, if not the author
Reply-To:address-listWhere 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: the Bcc: line is normally removed before the copies to To:/Cc: recipients are sent, and a Bcc: 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 example Tue, 23 Jun 2026 09:41:07 +0000. The zone is a four-digit offset from UTC; +0000 is UTC, and -0000 specifically means “generated where the local zone is unknown.” A malformed or missing Date: 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 the Message-ID of the message being replied to.
  • References: contains the chain of Message-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.0 declares 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, is text/plain; charset=us-ascii (RFC 2045 §5.2). A typical HTML email with a text fallback is a multipart/alternative, and RFC 2045 §5.1 requires a boundary parameter for any multipart type:
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, and base64. quoted-printable is used for mostly-ASCII text with a few high-bit characters; base64 for 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 envelope MAIL FROM domain. RFC 8601 §2.7.2 specifies the smtp ptype with mailfrom (or helo) here.
  • dkim=pass header.d=... - a DKIM signature validated for that signing domain (the d= value).
  • dmarc=pass header.from=... - DMARC passed, evaluated against the From: domain.
  • A bare ; none means 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 with d=, the verifier fetches the public key from s._domainkey.d in DNS.
  • h= is the list of signed headers - changing any of these in transit breaks the signature. Note whether from is 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-generated for periodic/cron output, auto-replied for automatic replies. A responder seeing any value other than no SHOULD NOT reply, which is the primary loop-prevention mechanism for vacation/auto-reply systems. At most one Auto-Submitted field 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 of Delivered-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:

  1. Return-Path: <bounce-7f3a@mail.shop.example> - bounces go to the shop’s automated mailbox, not to receipts@. The envelope sender’s domain (mail.shop.example) shares the From: Organizational Domain (shop.example), so it is SPF-aligned for DMARC.
  2. Delivered-To: alice@example.net - the address the final store actually delivered to.
  3. Received: block - read bottom-up: app-07.internal produced it, relay.shop.example relayed it out, mx.example.net accepted it, store.example.net delivered it locally over LMTP.
  4. Authentication-Results: - the receiver’s verdicts: SPF, DKIM, and DMARC all passed, with DMARC evaluated against header.from=shop.example.
  5. DKIM-Signature: - signed by shop.example (aligned with From:), selector mail2026, covering from among other headers.
  6. From: / To: / Subject: / Date: / Message-ID: - the human-facing message content and its unique identifier.
  7. List-Unsubscribe + List-Unsubscribe-Post - one-click unsubscribe is wired up (and must be inside the DKIM h= 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 see From:. DMARC only requires alignment between the From: domain and a passing SPF (MAIL FROM) or DKIM (d=) identifier - not header equality.
  • To: is who got the mail.” Not necessarily. RCPT TO is. Bcc: recipients and aliases never appear in To:.
  • “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: ...; none means 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 envelope MAIL 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.

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.

Talk to our team