How to Read Email Headers: A Forensic Guide to Tracking Senders, Routes, and Spoofing

June 13, 2026

#email forensics#email headers#email security#phishing analysis
How to Read Email Headers: A Forensic Guide to Tracking Senders, Routes, and Spoofing

How to Read Email Headers: A Forensic Guide to Tracking Senders, Routes, and Spoofing

The visual message displayed in your desktop or mobile email client represents merely the sanitized tip of the digital iceberg. Hidden behind the rendered HTML and styled fonts lies the raw internet mail header—the authoritative, machine-generated flight recorder of an electronic message.

Standardized by the Internet Message Format (RFC 5322) and the SMTP transport protocol (RFC 5321), email headers chronicle every Mail Transfer Agent (MTA) the message traversed, exact timestamped network delays, cryptographic identity assertions, spam telemetry, and underlying envelope routing.

Whether you are investigating a targeted phishing attempt, debugging delivery delays across corporate relays, or verifying whether a transactional receipt is genuine, learning how to read raw headers is an indispensable skill.


Before performing forensic analysis, you must capture the unadulterated MIME stream. Rendering engines often strip security headers from standard view.

  • Google Workspace / Gmail: Open the message → Click the three dots (More) in the upper right → Select Show original → Click Download Original.
  • Microsoft Outlook (Web): Open message → Click the three dots in the message bar → View → View message details.
  • Microsoft Outlook (Desktop): Double-click to open message in its own window → File → Properties → Inspect the Internet headers text box.
  • Apple Mail (macOS): Open message → Press Cmd + Shift + H (or menu View → Message → All Headers).

2. Anatomy of a Forensic Email Header: A Real-World Dissection

Below is an authentic, multi-hop header sample representing a message delivered to a production mailbox. We will break down its key security layers step by step:

Delivered-To: recipient@tmpkit.com
Received: by 2002:a05:6e02:1882:b0:3a9:975c:21fa with SMTP id g2csp1298517;
        Thu, 18 Jun 2026 04:12:35 -0700 (PDT)
X-Google-Smtp-Source: AGHT+IFg01V...
X-Received: by 2002:a17:907:7e09:b0:ab5:27f8:cb89 with SMTP id ym9mr4218320;
        Thu, 18 Jun 2026 04:12:34 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1718709154; cv=none;
        d=google.com; s=arc-20240605;
        b=N7r8L5p...
Authentication-Results: mx.google.com;
       dkim=pass header.i=@notifications.tmpkit.com header.s=202606 header.b=H4d9Qz;
       spf=pass (google.com: domain of bounces@mailer.tmpkit.com designates 198.51.100.42 as permitted sender) smtp.mailfrom=bounces@mailer.tmpkit.com;
       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=tmpkit.com
Received: from mailer.tmpkit.com (mailer.tmpkit.com. [198.51.100.42])
        by mx.google.com with ESMTPS id o18si4928120pll.128.2026.06.18.04.12.33
        for <recipient@tmpkit.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Thu, 18 Jun 2026 04:12:34 -0700 (PDT)
Received-SPF: pass (google.com: domain of bounces@mailer.tmpkit.com designates 198.51.100.42 as permitted sender) client-ip=198.51.100.42;
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=notifications.tmpkit.com; s=202606;
        h=from:to:subject:date:message-id:mime-version;
        bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
        b=H4d9QzO1...
Message-ID: <0100018f993f7421-4f1e3100-2d91-4c55-8911-c91837583a20@mailer.tmpkit.com>
Date: Thu, 18 Jun 2026 11:12:32 +0000
From: "TmpKit Security" <support@tmpkit.com>
To: recipient@tmpkit.com
Subject: Your Security Verification Code: 839201
Return-Path: <bounces@mailer.tmpkit.com>

3. The Three Critical Triage Checkpoints

When analyzing an unfamiliar or suspicious email, always inspect these three primary locations first:

[Raw Message Header]
  │
  ▼
[Checkpoint 1: Authentication-Results]
  │ Verify SPF, DKIM, and DMARC verdicts directly from receiving MX
  ▼
[Checkpoint 2: Trace Received Hops Bottom-Up]
  │ Extract the earliest hop to reveal originating IP & connecting MTA
  ▼
[Checkpoint 3: Identity Cross-Examination]
  │ Compare From: vs Return-Path: vs Message-ID domain consistency
  ▼
[Forensic Verdict: Legitimate / Phishing / Spoofed]

Checkpoint 1: The Authentication-Results Header

The single most efficient header to inspect is Authentication-Results. Generated by the recipient's incoming boundary MTA (in the sample above, mx.google.com), this field summarizes the mathematical verdicts of all cryptographic and IP checks:

  • dkim=pass: Confirms the cryptographic signature matches the public key in DNS. Pay close attention to header.i=—does the signing domain actually match the brand claim?
  • spf=pass: Verifies the connecting IP address (198.51.100.42) was explicitly authorized by the envelope domain's published SPF policy.
  • dmarc=pass: Confirms that either SPF or DKIM achieved identifier alignment with the visible From: support@tmpkit.com header. Note the enforced policy status (p=REJECT).

Warning: Adversaries cannot forge the Authentication-Results header written by your receiving mail server. However, if an email passed through multiple internal forwards, look exclusively at the Authentication-Results line stamped by your destination MX host.


Checkpoint 2: Tracing the Received: Trail (Bottom-to-Top)

Every intermediate SMTP server that handles an email prepends a new Received: header to the top of the stack. Because headers accumulate chronologically from bottom to top:

  • The Bottommost Received: line: Represents the initial ingestion point—where the sender's client or local mail submission agent (MSA) handed the message to the first outbound relay.
  • The Topmost Received: line: Represents the final handoff into the recipient's local storage mailbox.

Analyzing a Single Received Hop

Let us examine the incoming edge hop:

Received: from mailer.tmpkit.com (mailer.tmpkit.com. [198.51.100.42])
        by mx.google.com with ESMTPS id o18si4928120pll.128.2026.06.18.04.12.33
        for <recipient@tmpkit.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Thu, 18 Jun 2026 04:12:34 -0700 (PDT)
  1. from mailer.tmpkit.com: The identifier presented by the client during HELO/EHLO.
  2. (mailer.tmpkit.com. [198.51.100.42]): Crucial forensic evidence! The receiving server resolved the real TCP socket IP and performed reverse DNS (rDNS/PTR). Even if the attacker lies in the HELO, the bracketed IP [198.51.100.42] is stamped by the recipient's TCP kernel and cannot be faked.
  3. with ESMTPS: Indicates an Extended SMTP session negotiated with transport-layer encryption.
  4. version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384: Confirms state-of-the-art in-flight encryption.
  5. Thu, 18 Jun 2026 04:12:34 -0700: Stamped UTC/offset timestamp. Comparing timestamps across consecutive hops reveals exact transmission latency.

Checkpoint 3: Cross-Examining Identity Fields

Attackers routinely exploit subtle misalignments between display names, mailbox addresses, and return paths. Perform this three-way cross-examination:

| Header Field | Function | Legitimate Pattern | Phishing / Spoofing Tell | |---|---|---|---| | From: | Displayed to user | "Acme Support" <support@acme.com> | "Acme Support" <evil-phish@free-webmail.xyz> or display name impersonation | | Return-Path: | Envelope bounce target | <bounces@subdomain.acme.com> | <attacker@unrelated-hacked-site.com> | | Reply-To: | Routing address for user replies | Matches From: or official ticketing desk | Unrelated mailbox on a consumer provider (e.g., Gmail/ProtonMail) | | Message-ID: | Globally unique message GUID | <uuid@acme.com> (generated by corporate MTA) | Generic local hostnames like <123@localhost> or random strings from PHP scripts |


4. Advanced Forensics: Detecting Phishing & Spoofing Tactics

Tactic 1: Display Name Spoofing

Phishing actors often write a trusted identity inside the freeform display name while using an arbitrary sender address:

From: "Google Workspace Admin <admin@google.com>" <compromised_account@external-org.net>

Most mobile email clients truncate long addresses, showing only "Google Workspace Admin..." to the user. Inspecting the raw From: header immediately uncovers the discrepancy.

Tactic 2: Cousin Domains and Typosquatting

Subtle character substitutions are prevalent in Business Email Compromise (BEC):

  • Target Brand: paypal.com
  • Attacker Domain: paypa1.com or pаypal.com (using Cyrillic 'а' via IDN homograph attacks). Forensic headers reveal the Punycode translation (xn--pypal-4ve.com) in the raw MIME text.

Tactic 3: Broken ARC Chains (Authenticated Received Chain)

When emails pass through mailing lists or automated forwarders, DKIM and SPF often break. RFC 8617 (ARC) preserves authentication status across hops via:

  • ARC-Authentication-Results (AAR)
  • ARC-Message-Signature (AMS)
  • ARC-Seal (AS)

If cv=fail appears in the ARC-Seal header, an intermediary host altered message contents or tampered with the cryptographic sequence.


5. Automated CLI Analysis Script (Python)

When processing large batches of emails or suspicious headers from server logs, manual inspection is slow. You can parse raw MIME files rapidly using standard Python libraries:

#!/usr/bin/env python3
"""
Forensic Email Header Inspector
Usage: python3 inspect_headers.py sample_email.eml
"""
import sys
from email import policy
from email.parser import BytesParser

def analyze_email(file_path):
    with open(file_path, 'rb') as f:
        msg = BytesParser(policy=policy.default).parse(f)

    print("=== FORENSIC HEADER SUMMARY ===")
    print(f"Date:         {msg.get('Date')}")
    print(f"From:         {msg.get('From')}")
    print(f"To:           {msg.get('To')}")
    print(f"Subject:      {msg.get('Subject')}")
    print(f"Return-Path:  {msg.get('Return-Path')}")
    print(f"Message-ID:   {msg.get('Message-ID')}")
    print("\n=== AUTHENTICATION RESULTS ===")
    print(msg.get('Authentication-Results', 'None found'))

    print("\n=== TRANSMISSION ROUTE (RECEIVED HOPS) ===")
    received_hops = msg.get_all('Received', [])
    for idx, hop in enumerate(reversed(received_hops), start=1):
        clean_hop = " ".join(hop.split())
        print(f"Hop {idx}: {clean_hop[:120]}...")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Please provide path to an .eml file.")
        sys.exit(1)
    analyze_email(sys.argv[1])

6. Diagnostic Toolkit & Practical Workflows

To accelerate your email investigations:

  • Use our web-based Email Header Analyzer to paste raw MIME headers and immediately extract parsed hop latencies and SPF/DKIM/DMARC verdicts.
  • Review our foundational guide on SPF, DKIM, and DMARC Explained to understand why individual DNS records cause header check failures.
  • If investigating unexpected bounce backs, audit MX routing via our MX Lookup Tool.

Quick Forensic Checklist for Every Suspicious Email

  1. Locate Authentication-Results: Did dmarc, spf, and dkim pass with the expected domains?
  2. Examine Bottom Hop: Is the originating IP geographic location and ASN consistent with the claimed vendor?
  3. Compare Identities: Do From:, Return-Path:, and Reply-To: share the identical organizational root domain?
  4. Inspect Links & Domains: Are embedded hyperlinks targeting the domain declared in the header, or an unrelated tracking redirect?

By treating email headers as evidentiary audit trails, security professionals and developers can cut through display illusions and establish cryptographic truth.