
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.
Cmd + Shift + H (or menu View → Message → All Headers).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>
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]
Authentication-Results HeaderThe 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-Resultsheader written by your receiving mail server. However, if an email passed through multiple internal forwards, look exclusively at theAuthentication-Resultsline stamped by your destination MX host.
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:
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.Received: line: Represents the final handoff into the recipient's local storage mailbox.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)
from mailer.tmpkit.com: The identifier presented by the client during HELO/EHLO.(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.with ESMTPS: Indicates an Extended SMTP session negotiated with transport-layer encryption.version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384: Confirms state-of-the-art in-flight encryption.Thu, 18 Jun 2026 04:12:34 -0700: Stamped UTC/offset timestamp. Comparing timestamps across consecutive hops reveals exact transmission latency.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 |
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.
Subtle character substitutions are prevalent in Business Email Compromise (BEC):
paypal.compaypa1.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.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.
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])
To accelerate your email investigations:
Authentication-Results: Did dmarc, spf, and dkim pass with the expected domains?From:, Return-Path:, and Reply-To: share the identical organizational root domain?By treating email headers as evidentiary audit trails, security professionals and developers can cut through display illusions and establish cryptographic truth.