Received Headers and the Email Trace Chain: A Practical Reading Guide (RFC 5322)

Received headers form the trace chain of every MTA that handled the email. Covers RFC 5322 §3.6.7 format, the trace fields (from, by, via, with, id, for), how to read a chain bottom-up, a worked Gmail → SendGrid → Postfix example, related trace headers (Return-Path, Delivered-To), and 10 issues you can spot in a Received chain (delays, loops, TLS downgrades, forwarders).
Alaa
By Alaa
SMTPedia documents email infrastructure end to end: SMTP standards from the RFC archive, delivera...
13 min read Updated Jul 12, 2026 123 views

Email headers series. This is the tactical guide to reading Received headers and the full trace chain. For the RFC catalog and other header deep-dives, see the headers and MIME hub →

Quick Received-chain reference

Received headers are the forensic trail every email carries. Each MTA that accepts the message prepends a new Received line at the top, building an append-only chain. Reading it bottom-up tells you exactly which servers touched the message, in what order, over what encryption, and how long each hop took.

SpecRFC 5322 §3.6.7 + RFC 5321 §4.4
OrderNewest at top, oldest at bottom
Written byThe receiving side of each hop
ModificationNever rewritten, only prepended
Key fieldsfrom, by, via, with, id, for, timestamp
Reading directionBottom-up (chronological)

Every email delivery problem eventually comes down to reading a Received chain. Which MTA rejected the message. Where the 45-second delay came from. Whether the TLS handshake happened where you thought it did. Which forwarder is stripping DKIM signatures. All of it is in the trace. This guide covers the exact format, what each field means, how to read a real chain end to end, and the 10 issues that show up most often in production.

What Received headers are

A Received header is a single line written by an MTA when it accepts a message from another MTA (or from a submitting client). Each hop in the delivery chain adds one Received line. The line is prepended to the top of the header block, above any existing Received lines from earlier hops. The result is a reverse-chronological stack: the newest hop is at the top, the oldest at the bottom.

Two properties make Received headers useful for forensics:

  • Append-only. Once written, a Received line is never rewritten. Every MTA that later handles the message adds its own line above the existing chain, but does not touch what came before.
  • Written by the receiver. The MTA that accepts the message writes the Received line, not the sender. This means the trace records the receiver’s view of the sender, including verified information (source IP, reverse DNS, TLS state) that the sender cannot forge.

The receiver-writes rule is critical for spam and anti-spoofing work: the source IP shown in a Received header is the actual IP that connected to that MTA. A sender who claims a different HELO name or forges other fields cannot forge the IP the receiver observes.

The exact format (RFC 5322 §3.6.7 and RFC 5321 §4.4)

The core syntax is:

Received: from <source> by <destination> [via <link>]
          [with <protocol>] [id <queue-id>] [for <recipient>];
          <timestamp>

The keywords (from, by, via, with, id, for) are case-insensitive. Their order is flexible in the specification but conventionally follows the sequence above. A semicolon separates the trace fields from the timestamp at the end.

A minimal Received header can have just from, by, and a timestamp. A rich one includes every optional field. In practice, modern MTAs write most of the fields; missing fields usually indicate a legacy or misconfigured server.

The trace fields, one by one

from

Identifies the source of the message at this hop. Contains three sub-elements when fully populated:

  • The HELO/EHLO value the sender advertised (a hostname, sometimes forged).
  • The reverse DNS name of the source IP, in parentheses.
  • The actual source IP, in square brackets. This is the verified truth.

Example: from mta-05.sender.example.com (mta-05.sender.example.com [203.0.113.42])

by

The hostname of the MTA that is accepting the message and writing this Received line. This is the receiver’s own name.

Example: by mx.google.com

via

The transport used. Almost universally TCP. Rarely surfaces meaningful information; often omitted.

with

The email protocol variant used for the SMTP conversation. This field encodes crucial security information:

ValueMeaning
SMTPPlaintext RFC 5321 SMTP, no extensions
ESMTPExtended SMTP (EHLO advertised extensions), no TLS or auth
ESMTPSESMTP with STARTTLS (TLS negotiated)
ESMTPAESMTP with SMTP AUTH (authenticated submission)
ESMTPSAESMTP with both STARTTLS and AUTH (typical submission)
LMTPLocal Mail Transfer Protocol (delivery to a local mailbox store)

If you are debugging a TLS problem, the with field is where you look. A hop with with ESMTP (no S) means TLS was not negotiated, even if the sender’s policy required it.

id

The queue ID assigned by the accepting MTA to this message. Local to that MTA only, changes at every hop. Do not confuse with the globally unique Message-ID header. The id in Received is a per-server queue identifier; the Message-ID is the global message identifier.

for

The envelope recipient (RCPT TO) that this hop is delivering to. Useful when a message was sent to multiple recipients or through a forwarder: the for field records who the current hop is trying to reach, which may differ from the To: header.

timestamp

The date and time the MTA accepted the message, in RFC 5322 date format. Includes the timezone offset. Comparing timestamps across the Received chain tells you where delays occurred.

How to read a Received chain

The chain is written in reverse chronological order: newest hop at the top, oldest at the bottom. To follow the message’s actual journey, read bottom-up.

  1. Start at the bottom Received header. This is the submission or first-hop MTA, closest to the original sender.
  2. Read the from field: this is the source IP and hostname of the sender.
  3. Read the by field: this is the first MTA that accepted the message.
  4. Move up one Received line. The next hop’s from should be the previous hop’s by. If they do not match, either a hop is missing (rare, means a header was stripped) or a forwarder inserted itself.
  5. Continue upward until you reach the final delivery hop at the top.

Two things to watch for as you climb:

  • Time gaps. Compare timestamps at each hop. Anything over a few seconds is worth investigating. Ten-minute gaps often mean the receiving MTA greylisted the message; hour-plus gaps often mean queue congestion or repeated 4xx deferrals.
  • TLS status per hop. The with field tells you whether the hop used encryption. A message that goes ESMTPS → ESMTPS → ESMTP lost TLS at the last hop, which is a downgrade the sender did not authorize.

A worked example: reading a real trace chain

Here is a real Received chain for a message that traveled: sender’s Postfix MTA → SendGrid relay → Gmail inbound. Read bottom-up.

Received: by 2002:a05:6402:1234:b0:456 with SMTP id abc123csp;
        Wed, 02 Jul 2026 07:14:38 -0700 (PDT)
Received: from geopod-ismtpd-3-1.sendgrid.net (geopod-ismtpd-3-1.sendgrid.net.
        [167.89.123.45]) by mx.google.com with ESMTPS id def456
        for <user@example.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Wed, 02 Jul 2026 07:14:37 -0700 (PDT)
Received: from mta-05.sender.example.com (mta-05.sender.example.com
        [203.0.113.42]) by geopod-ismtpd-3-1.sendgrid.net with ESMTPS id ghi789
        for <user@example.com>
        (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256);
        Wed, 02 Jul 2026 14:14:35 +0000 (UTC)
Received: from app-server-01.sender.example.com (localhost [127.0.0.1])
        by mta-05.sender.example.com (Postfix) with ESMTPA id jkl012
        for <user@example.com>;
        Wed, 02 Jul 2026 14:14:34 +0000 (UTC)

Reading bottom-up:

  1. 14:14:34 UTC: The application server (app-server-01) submits the message to the local Postfix MTA over SMTP AUTH (ESMTPA). This is the origin hop.
  2. 14:14:35 UTC (1 second later): The Postfix MTA hands off to SendGrid over STARTTLS with authentication (ESMTPS). Fast, encrypted, expected.
  3. 14:14:37 UTC (2 seconds later): SendGrid relays to Gmail’s MX (mx.google.com) over ESMTPS. TLS 1.3, AES-256-GCM. Clean.
  4. 14:14:38 UTC (1 second later): Gmail’s internal delivery hop, no TLS field because it is intra-datacenter.

Total delivery time: 4 seconds. Every hop used TLS. No unexpected forwarders. This is what a healthy chain looks like.

Other trace-related headers

Received is the primary trace header, but several others carry related information:

Return-Path

Written by the final delivery MTA (the one that puts the message in the mailbox). Records the envelope sender (MAIL FROM), which is the address bounces go to. Often different from the visible From: header, especially for ESP-sent mail where the envelope sender is a variable-envelope-return-path (VERP) address for bounce tracking.

Delivered-To

Written by the delivery MTA to record the final mailbox address. Useful for detecting forwarding: if Delivered-To differs from the To: header, the message was forwarded at some point.

X-Received

Gmail-specific. An internal trace of Gmail’s own datacenter routing. Not part of the standard trace chain; useful only within Google’s infrastructure.

X-Original-To

Postfix-specific. Records the original envelope recipient before any alias expansion or forwarding. Useful for debugging aliases and mail routing.

Authentication-Results

Written by the receiver to record SPF, DKIM, DMARC, and ARC check outcomes. Not a Received header per se, but part of the same forensic block. See our dedicated Authentication-Results guide.

What Received chains diagnose

Delivery delays

Compare timestamps at each hop. A gap between two consecutive Received lines is delay at the receiving MTA of that hop: either queue congestion, greylisting (typical 5 to 15 minutes), or repeated 4xx deferrals. A gap in the middle of an otherwise fast chain usually means the intermediate MTA had a temporary problem.

Loops

A message can bounce between two MTAs when forwarding rules or aliases create a cycle. The Received chain grows quickly, and you see the same two by hostnames alternating. Anti-loop protection (Received-line count limit, usually 25 or 30 lines) eventually kicks in and rejects the message.

Forwarders

A forwarder inserts an unexpected hop in the middle of the chain. If a message from Gmail (source) to Yahoo (destination) has a from field halfway up that reads from forward-server.example.net, that MTA forwarded the message. Forwarders are the main reason DMARC breaks for legitimate mail: they resend the message from their IP, breaking SPF alignment.

TLS downgrades

If any hop has with ESMTP (no S) when neighboring hops have ESMTPS, that hop lost TLS. Either the receiving MTA on that hop did not advertise STARTTLS, or a middlebox stripped the advertisement. For sensitive infrastructure, this is a signal to deploy MTA-STS or DANE to enforce TLS.

Header injection attempts

An extra Received line inserted mid-chain, with a nonsensical from or a suspicious hostname, is often the signature of a compromised or malicious MTA trying to fake a trace. Real Received chains have consistent from to by continuity: each hop’s from matches the previous hop’s by.

10 issues you can spot in a Received chain

  1. Missing Received headers entirely. A message with only one Received line and no submission trace often came from a spam campaign that bypassed submission MTAs.
  2. Broken continuity between hops. Hop 2’s from should be Hop 1’s by. When they diverge, a header was inserted or stripped.
  3. TLS lost mid-chain. ESMTPS → ESMTP → ESMTPS: the middle hop dropped encryption. Investigate whether that MTA supports STARTTLS.
  4. Long time gap on a specific hop. 10+ minute delay usually means greylisting; hour-plus usually means queue congestion or repeated 4xx.
  5. Unexpected forwarder. An extra hop from a domain you did not expect. Common source of DMARC failures.
  6. Reverse DNS mismatch. In the from field, the HELO name and the reverse DNS name should be sensible. A HELO of friend with reverse DNS dsl-user-192-168-1-1.isp.example.net is a botnet fingerprint.
  7. Excessive hop count. More than 5 or 6 Received lines is unusual for regular mail. 20+ suggests a loop.
  8. Timestamps out of order. Each higher Received line should have a later timestamp than the one below. A hop with an earlier timestamp indicates clock skew on that MTA (a diagnostic issue, not necessarily malicious).
  9. Missing id field. Legacy or minimal MTAs skip it. Not a fault, but makes cross-server log correlation harder.
  10. IP does not match the from hostname. The IP in square brackets should reverse-resolve to the hostname in parentheses. Mismatch is a classic spam signal that receivers score on.

Received-headers FAQ

Do I read Received headers top-down or bottom-up?

Bottom-up. Each MTA prepends its Received line to the top of the header block, so the top line is the last hop (most recent) and the bottom line is the first hop (oldest). Reading bottom-up follows the message’s actual chronological journey from sender to receiver.

Can a sender forge Received headers?

A sender can add fake Received headers at the bottom of the chain to make the trace look like it originated somewhere else. What a sender cannot forge is the top of the chain: any Received line added by the actual receiving MTA (the one whose IP the receiver controls) is trustworthy. Anti-spam systems trust Received lines starting from the first hop whose by field they recognize as their own infrastructure, and treat everything below it as potentially forged.

What is the difference between Return-Path and the From: header?

Return-Path records the envelope sender (MAIL FROM in the SMTP conversation), which is where bounces are delivered. The From: header records the visible sender that appears in the recipient’s mail client. They are often different: an ESP typically uses a variable Return-Path for bounce tracking (like bounce+abc123@sender.example.com) while the From: shows the brand’s normal address. DMARC alignment checks whether the two domains match, per SPF and DKIM alignment rules.

How do I tell if TLS was used on every hop?

Check the with field on every Received line. Values ending in S (ESMTPS, ESMTPSA) mean STARTTLS was negotiated. Values without S (ESMTP, ESMTPA) mean the hop was plaintext. Modern chains should show ESMTPS (or ESMTPSA on the submission hop) at every step. Any plaintext hop is a downgrade risk. To enforce TLS on inbound hops, deploy MTA-STS as covered in our TLS setup guide.

Why does the queue id keep changing?

The id field inside each Received header is a queue identifier local to the MTA that wrote it. When the message moves to the next MTA, that MTA assigns its own queue ID and writes it in its own Received line. The IDs are useful for local log correlation on each server but do not carry across hops. For cross-server correlation, use the Message-ID header, which is globally unique and stable end-to-end.

What causes a large time gap between two Received hops?

Three main causes: greylisting (the receiving MTA temporarily deferred the message with a 4xx response, and the sender retried after 5 to 15 minutes), queue congestion at the receiving MTA (the message sat in queue before being processed), and repeated deferrals (the sender retried multiple times before the receiver accepted). A gap of a few seconds is normal. A gap of many minutes to hours indicates one of the above; check the receiver’s logs for the specific reason.

Final words

Received headers are the black box recorder of email. When a message arrives, they tell you exactly which servers touched it, in what order, with what encryption, at what times. When a message goes missing, they tell you where it stopped. Every deliverability investigation, every forensic analysis of a phishing attempt, every debugging session for a mysterious delivery delay starts with reading the trace chain bottom-up.

The muscle memory to build: read bottom-up, watch the from to by continuity, check the with field for TLS, compare timestamps for delay location. Everything else in the chain is context. Every mail server writes them, every receiver reads them, and the ones you write on your own MTA get read by every downstream server.

For related headers, see our guides on the Message-ID header, the Authentication-Results header, and the SSL/TLS setup for email.

Every Received line is only useful if the message actually reaches the mailbox.

SMTPing catches disposables, role-based, catch-all, syntax errors, dead mailboxes and traps before they turn your carefully traced hops into hard bounces. 13 validation types, 25 free daily.

Try SMTPing →

About the Author

Alaa - SMTPedia author

Alaa · LinkedIn

Email infrastructure specialist with 8+ years of hands-on experience in SMTP, deliverability, and email verification. I’ve configured and troubleshot mail systems across Postfix, Exchange, and cloud relays, managed IP reputation and warmup campaigns, and built verification pipelines processing millions of addresses. My work spans DNS authentication (SPF, DKIM, DMARC, BIMI), bounce handling, blocklist monitoring, and compliance frameworks including CAN-SPAM and GDPR. I write every article on SMTPedia to give email professionals, developers, and marketers the accurate, RFC-grounded reference they need.


About SMTPedia

SMTPedia is an independent email industry reference covering SMTP, IMAP, POP3, email deliverability, marketing platforms, DNS authentication, and email verification. Every article is researched from official provider documentation, IETF RFCs, and industry best practices. Settings and configurations are verified quarterly.

We are cited as a source by ChatGPT, Microsoft Copilot, and thousands of email professionals worldwide. Learn more about our editorial process.