Every email contains more than the sender, recipient, subject, and message body.
Behind the content is a set of email headers that record information about the message, including where it came from, which servers handled it, how it was authenticated, how its content is formatted, and more.
For developers, these headers are part of the email behavior you need to test.
A transactional email can look completely correct while still using the wrong Reply-To, failing authentication, missing an unsubscribe header, or losing application-specific metadata somewhere during delivery.
In this guide, we'll explain what email headers are, how to read them, which fields matter, and how to test the headers that affect your application's emails.
What is an email header?
An email header is the structured metadata section at the beginning of an email message.
It contains familiar fields such as:
From
To
Subject
Date
but also technical information about:
- email routing
- authentication
- sender identities
- message identifiers
- MIME and content structure
- mailing-list behavior
- application or provider metadata
In simple terms:
The email body contains the message. The email headers contain information about the message and how it was delivered.
Email clients normally display only a small subset of these fields. Opening the full headers reveals much more detail.
Technical email headers vs visual email headers
The phrase "email header" can also refer to the visual area at the top of a marketing email, such as a logo, banner, or navigation.
That is not what we're discussing here.
This guide is about technical email headers, the metadata fields that form part of the email message itself.
An email preheader is different too. A preheader is the preview text some email clients display next to or below the subject line. It normally comes from the message content rather than the technical header section.
Email headers: the short version
If you just need to inspect or debug an email:
- Check
Authentication-Resultsfor SPF, DKIM, and DMARC. - Read trusted
Receivedheaders from bottom to top to trace the delivery path. - Compare
From,Reply-To, andReturn-Path. - Compare
Receivedtimestamps if the email arrived late. - Check
Content-Typeand other MIME fields for rendering or attachment problems. - Inspect custom headers when debugging application-specific metadata.
If you're testing emails generated by your application, focus on the fields that affect actual behavior rather than trying to assert every header.
Why should developers test email headers?
Email testing often focuses on what users can see:
- subject line
- HTML
- plain-text version
- links
- attachments
But important behavior also lives in the headers.
A message may render correctly while still having a problem such as:
| Problem | Header to inspect or test |
|---|---|
| Replies go to the wrong mailbox | Reply-To |
| Wrong sender identity | From, Sender |
| Bounces are handled incorrectly | Return-Path |
| SPF or DKIM fails | Authentication-Results |
| DMARC fails | Authentication-Results, From |
| Unsubscribe support is missing | List-Unsubscribe |
| One-click unsubscribe is missing | List-Unsubscribe-Post |
| Application metadata disappears | Custom headers |
| Email cannot be correlated with logs | Message-ID or custom ID |
| HTML or attachments behave incorrectly | MIME headers |
This is why end-to-end email testing is useful.
Testing the object your application sends only proves what your code attempted to create.
Testing the email that actually arrived lets you verify what survived the complete delivery path.
What does an email header look like?
Here is a simplified example:
Return-Path: <[email protected]>
Authentication-Results: mx.example.net;
spf=pass smtp.mailfrom=mail.example.com;
dkim=pass header.d=example.com header.s=selector1;
dmarc=pass header.from=example.com
Received: from outbound.example.net (outbound.example.net [203.0.113.10])
by mx.example.net with ESMTPS
for <[email protected]>;
Tue, 18 Aug 2026 09:14:22 +0000
Received: from app.example.com (app.example.com [192.0.2.15])
by outbound.example.net with ESMTPS;
Tue, 18 Aug 2026 09:14:20 +0000
DKIM-Signature: v=1; a=rsa-sha256;
d=example.com; s=selector1;
h=from:to:subject:date;
bh=...;
b=...
From: Acme Billing <[email protected]>
To: [email protected]
Reply-To: [email protected]
Subject: Your invoice is ready
Date: Tue, 18 Aug 2026 09:14:19 +0000
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="abc123"
You can learn quite a lot from this one message.
Who does the message identify as the sender?
From: Acme Billing <[email protected]>
The visible author is [email protected].
Where will replies go?
Reply-To: [email protected]
Replies should be directed to [email protected].
That is worth testing because an incorrect Reply-To can silently route customer responses to the wrong inbox.
Did authentication pass?
spf=pass
dkim=pass
dmarc=pass
The receiving system reported successful SPF, DKIM, and DMARC checks.
Which domain signed the email?
d=example.com
s=selector1
The DKIM signing domain is example.com, and selector1 is the selector used to find its public key.
What route did the message take?
Read the Received headers from bottom to top:
app.example.com
↓
outbound.example.net
↓
mx.example.net
Each trusted receiving server added information about the handoff it observed.
What could you test automatically?
For a message like this, an automated test might verify that:
Fromuses the expected addressReply-Topoints to the correct support mailbox- the expected
Message-IDexists - a custom transaction header is present
List-Unsubscribeexists where required- SPF or DKIM produced the expected result
The exact assertions depend on what matters to your application.
Common email header fields
Here are the fields you're most likely to encounter:
| Header | What it tells you |
|---|---|
From | The message author or authors |
To | Primary recipients shown in the message |
Cc | Additional recipients shown in the message |
Bcc | Blind-copy recipients during message creation, normally withheld from other delivered copies |
Sender | The agent responsible for transmitting a message when different from the author |
Reply-To | Where replies should be directed |
Subject | The email subject |
Date | The message's stated origination date and time |
Message-ID | An identifier intended to uniquely identify the message |
Return-Path | The SMTP reverse-path recorded at final delivery |
Received | A record of a mail handoff |
Authentication-Results | Results of authentication checks reported by a mail system |
Received-SPF | Information about an SPF evaluation |
DKIM-Signature | The message's DKIM signature |
MIME-Version | The MIME version used by the message |
Content-Type | The type and structure of the message content |
Content-Disposition | How a MIME part should be presented |
Content-Transfer-Encoding | How a MIME part is encoded for transport |
In-Reply-To | Identifies a message this email replies to |
References | Message identifiers used to relate messages in a thread |
List-Unsubscribe | Methods a recipient can use to unsubscribe |
List-Unsubscribe-Post | Can indicate support for one-click unsubscribe |
Auto-Submitted | Indicates certain automatically generated messages |
ARC-* | Authentication information carried through intermediaries |
| Custom headers | Application, provider, or system-specific metadata |
A real email can contain dozens of fields.
You usually only need to inspect the ones related to the problem you're investigating.
Email header vs SMTP envelope vs preheader
These terms are related but refer to different things.
| Term | What it is |
|---|---|
| Email header | Metadata inside the message, such as From, Subject, and Message-ID |
| SMTP envelope | Delivery information used during SMTP, including MAIL FROM and RCPT TO |
| Email body | The plain-text, HTML, and attachment content |
| Email preheader | Preview text displayed by some email clients beside the subject |
This distinction matters because the addresses used during SMTP delivery do not have to match the addresses displayed in the message.
For example:
SMTP MAIL FROM:
[email protected]
Message header:
From: [email protected]
SPF normally evaluates an SMTP identity, while DMARC compares authenticated domains with the domain visible in the message's From field.
How to view the full headers of an email
Email clients normally show only a small subset of the headers.
How to view email headers in Gmail
In Gmail in a web browser:
- Open the email.
- Click the three-dot More menu next to Reply.
- Select Show original.
Gmail opens the original message with its full headers and authentication information.
How to view email headers in Outlook
In new Outlook or Outlook on the web:
- Open the email.
- Select More actions.
- Select View > View message details.
In classic Outlook for Windows:
- Open the message in its own window.
- Select File > Properties.
- Look for Internet headers.
How to view email headers in Apple Mail
In Mail on macOS:
View > Message > All Headers
This displays detailed header fields for the message.
How to inspect test emails in testmail.app
If you're debugging an email generated by your application, you do not need to send it to your personal Gmail or Outlook inbox.
Send the message to your testmail.app inbox instead.
If your plan includes the Visual Viewer, open the received email and select the Headers tab.

This is useful when you know which field you're looking for and do not want to dig through the complete raw message.
For automated testing, testmail.app can also return the headers through its API. We'll cover that later.
Don't forward an email if you need its original headers
Forwarding normally creates a new message and can add or change headers.
If you need to investigate the original delivery path, authentication results, or timestamps, retrieve the original headers from the email client rather than forwarding the message normally.
How to read an email header
Most headers follow this format:
Header-Name: value
For example:
From: Acme <[email protected]>
Content-Type: text/html; charset=UTF-8
Message-ID: <[email protected]>
Header values can span multiple lines
Long header fields may continue across multiple physical lines.
For example:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com;
s=selector1; h=from:to:subject:date;
bh=...
The continuation belongs to the same logical header field.
The same header can occur more than once
Received is the most common example:
Received: from mail1.example.com by mail2.example.net ...
Received: from app.example.com by mail1.example.com ...
This is normal.
Different mail systems add information as the message moves through the delivery infrastructure.
How to read Received headers
Received headers record mail handoffs.
They are particularly useful when you're investigating routing or delivery delays.
A typical entry might look like:
Received: from mail.example.com (mail.example.com [203.0.113.10])
by mx.example.net with ESMTPS
for <[email protected]>;
Tue, 18 Aug 2026 09:14:22 +0000
It can tell you:
from: information about the connecting system- IP address: the connecting host observed for that handoff
by: the server that accepted the messagewith: the protocol or transport usedfor: sometimes the recipient associated with the delivery- timestamp: when the handoff occurred
The exact format varies between mail systems.
Read Received headers from bottom to top
Mail servers prepend new Received fields, so the newest entry normally appears at the top.
For example:
Received: from mx2.example.net by inbox.example.com ...
Received: from mx1.example.net by mx2.example.net ...
Received: from app.example.com by mx1.example.net ...
Read them upward from the bottom:
app.example.com
↓
mx1.example.net
↓
mx2.example.net
↓
inbox.example.com
This can help you identify:
- which systems handled the message
- an unexpected relay
- the IP used for a particular handoff
- where a delivery delay may have occurred
Use timestamps to find delays
Suppose you see:
Received: by inbox.example.com;
Tue, 18 Aug 2026 09:10:02 +0000
Received: by relay.example.net;
Tue, 18 Aug 2026 09:02:41 +0000
Received: by mail.example.com;
Tue, 18 Aug 2026 09:02:39 +0000
The early handoff took around two seconds, but there was a gap of more than seven minutes before the final server accepted the message.
That gives you a useful place to start investigating.
Keep in mind that timestamps depend on the clocks of the systems that generated them, so small differences are not necessarily meaningful.
Don't blindly trust every Received header
A sender can construct header fields before handing a message to trusted mail infrastructure.
When investigating a suspicious or malformed message, establish which receiving systems you trust and work backward through the fields those systems added.
Do not assume every earlier line is independently verified evidence.
Authentication headers: SPF, DKIM, and DMARC
When you're debugging email authentication, start with Authentication-Results.
For example:
Authentication-Results: mx.example.net;
spf=pass smtp.mailfrom=example.com;
dkim=pass header.d=example.com;
dmarc=pass header.from=example.com
This tells you that the system identified as mx.example.net reported successful SPF, DKIM, and DMARC checks.
Authentication-Results
Authentication-Results records authentication results reported by a mail system.
You may see:
spf=pass
dkim=pass
dmarc=pass
Depending on the mechanism, other results can include:
fail
softfail
neutral
none
temperror
permerror
The important question is who added the header.
An arbitrary:
Authentication-Results: example.com; dkim=pass
does not prove that DKIM passed.
Trust authentication results added by receiving systems within a trust boundary you recognize.
How to check SPF in email headers
SPF results may appear inside Authentication-Results:
spf=pass smtp.mailfrom=example.com
You may also see:
Received-SPF: pass
client-ip=203.0.113.10;
[email protected];
SPF normally checks whether the connecting server is authorized to use the domain in the SMTP MAIL FROM identity.
If the SMTP reverse-path is empty, SPF can use the HELO identity instead.
This is why the domain evaluated by SPF may differ from the address users see in From.
How to check DKIM in email headers
DKIM adds a cryptographic signature to the message:
DKIM-Signature: v=1;
a=rsa-sha256;
d=example.com;
s=selector1;
h=from:to:subject:date;
bh=...;
b=...
Useful fields include:
| Field | Meaning |
|---|---|
a= | Signing algorithm |
d= | Signing domain |
s= | Selector used to locate the public key |
h= | Header fields covered by the signature |
bh= | Hash of the message body |
b= | Cryptographic signature |
The presence of a DKIM-Signature field does not mean DKIM passed.
Look at the result recorded by a trusted receiving system:
dkim=pass header.d=example.com
How to check DMARC in email headers
DMARC checks whether the domain visible in From aligns with a domain that successfully authenticated through SPF or DKIM.
DMARC passes when at least one of those mechanisms passes with the required alignment.
The current DMARC specification is RFC 9989, published in May 2026.
This result can therefore be valid:
spf=fail
dkim=pass
dmarc=pass
DKIM was sufficient because it passed and its authenticated domain aligned with the domain in From.
Passing SPF, DKIM, and DMARC still does not prove that an email is safe or trustworthy.
These mechanisms authenticate domains, authorization, signatures, and alignment. They do not establish the sender's intentions.
From vs Sender vs Reply-To vs Return-Path
An email can contain several sender-related identities.
For example:
From: Acme Billing <[email protected]>
Reply-To: [email protected]
Return-Path: <[email protected]>
They serve different purposes.
| Field | Purpose |
|---|---|
From | Identifies the message author shown to the recipient |
Sender | Identifies the agent responsible for transmission when required |
Reply-To | Tells the email client where replies should go |
Return-Path | Records the SMTP reverse-path at final delivery |
| Envelope sender | Identity supplied using SMTP MAIL FROM |
Why test Reply-To?
Consider:
From: [email protected]
Reply-To: [email protected]
The user sees the message as coming from [email protected], but selecting Reply sends the response to [email protected].
If your application accidentally changes or drops Reply-To, the message can still look perfect while customer replies go somewhere unexpected.
That makes Reply-To a good candidate for an automated email test.
Why test Return-Path?
During SMTP delivery, the sending system supplies a reverse-path using MAIL FROM.
Conceptually:
Envelope sender: [email protected]
Message header:
From: [email protected]
At final delivery, the receiving mail system records the reverse-path in Return-Path.
This address is commonly associated with bounce handling and can differ from the visible From address.
Message-ID, In-Reply-To, and References
These fields help identify individual messages and relationships between them.
Message-ID
For example:
Message-ID: <[email protected]>
A Message-ID is intended to uniquely identify a message.
It can be useful for:
- correlating email with application logs
- debugging duplicate messages
- connecting replies and threads
- referring to a specific email during support investigations
For an application that depends on reliable message correlation, checking that a Message-ID exists can be useful.
In-Reply-To
A reply may contain:
In-Reply-To: <[email protected]>
This identifies the message being replied to.
References
References: <[email protected]> <[email protected]>
This can contain message identifiers associated with the conversation and is commonly used by clients to help construct threads.
Content and MIME headers
If an email's HTML, plain text, character encoding, or attachments look wrong, check its MIME-related headers.
Common fields include:
MIME-Version
Content-Type
Content-Disposition
Content-Transfer-Encoding
For example:
Content-Type: text/html; charset=UTF-8
This says that the content is HTML using UTF-8 character encoding.
An email containing plain-text and HTML versions may use:
Content-Type: multipart/alternative;
boundary="abc123"
Attachments are represented as MIME parts too:
Content-Type: application/pdf; name="invoice.pdf"
Content-Disposition: attachment; filename="invoice.pdf"
You may also encounter:
Content-Transfer-Encoding: quoted-printable
or:
Content-Transfer-Encoding: base64
You generally do not need to decode these manually. Email clients, libraries, and testing tools can parse them for you.
Testing unsubscribe headers
Subscription and marketing messages may contain:
List-Unsubscribe: <https://example.com/unsubscribe/...>
You may also see:
List-Unsubscribe-Post: List-Unsubscribe=One-Click
These headers can allow supporting email clients and providers to expose easier unsubscribe actions.
For applications that send subscription email, these are good candidates for end-to-end tests because the rendered email can look correct even if the underlying unsubscribe metadata is missing.
For example, you might test that:
List-Unsubscribeexists- the expected unsubscribe URL or address is present
List-Unsubscribe-Postis present when your implementation requires one-click unsubscribe support
Testing custom email headers
Applications and email providers frequently add custom metadata:
X-Environment: staging
X-Transaction-ID: txn_12345
X-Campaign-ID: campaign_456
Custom headers do not have to begin with X-, although X- names remain common in real-world systems.
They can be useful for:
- matching an email to application logs
- identifying the environment that generated it
- storing transaction or campaign identifiers
- passing provider-specific metadata
- verifying that expected metadata survived delivery
This is especially useful in automated testing.
Your application may correctly construct:
X-Environment: staging
but an end-to-end email test verifies that the header was still present on the message that actually arrived.
What are ARC headers?
You may encounter:
ARC-Seal
ARC-Message-Signature
ARC-Authentication-Results
ARC stands for Authenticated Received Chain.
ARC allows intermediaries such as forwarding services and mailing lists to build a cryptographically verifiable chain containing information about how a message was handled and authenticated.
This can give a later receiver additional information when forwarding causes SPF to fail or message modification affects DKIM.
ARC does not simply make failed SPF or DKIM pass again.
For most application testing, you will not need to inspect ARC first.
Start with:
ReceivedAuthentication-ResultsDKIM-SignatureFromReturn-Path
Which email header should I check?
You normally do not need to inspect every field.
| Problem | Start with |
|---|---|
| Email took too long to arrive | Received timestamps |
| Unexpected delivery route | Received |
| SPF failed | Authentication-Results, Received-SPF |
| DKIM failed | Authentication-Results, DKIM-Signature |
| DMARC failed | Authentication-Results, From, SPF and DKIM identities |
| Replies go to the wrong inbox | Reply-To, From |
| Wrong bounce address | Return-Path, envelope sender |
| HTML displays incorrectly | Content-Type, MIME structure |
| Attachment is missing | Content-Type, Content-Disposition |
| Unsubscribe metadata is missing | List-Unsubscribe, List-Unsubscribe-Post |
| Custom metadata is missing | Relevant custom header |
| Need to correlate with logs | Message-ID or custom transaction header |
| Need to investigate a delay | Trusted Received headers |
If authentication failed, start with Authentication-Results and then inspect the information associated with the failing mechanism.
How to test email headers with testmail.app
Manual inspection is useful while debugging.
Automated tests are more useful when you need to make sure the same behavior remains correct every time your application sends email.
testmail.app lets you retrieve the headers from emails received in your test inbox using its JSON and GraphQL APIs.
Query headers with the JSON API
Add:
&headers=true
to your JSON API request.
For example:
https://api.testmail.app/api/json?apikey=YOUR_APIKEY&namespace=YOUR_NAMESPACE&tag=YOUR_TAG&headers=true
The returned email object includes a headers array:
{
"headers": [
{
"line": "Message-Id: <[email protected]>",
"key": "message-id"
},
{
"line": "Mime-Version: 1.0",
"key": "mime-version"
}
]
}
Header keys are normalized to lowercase, while line contains the original header text.
In GraphQL, include the headers field among the email fields you request.
Assert a header in your automated test
Once you have retrieved the email, you can find a particular field:
const replyTo = email.headers.find(
header => header.key === 'reply-to'
);
expect(replyTo).toBeDefined();
expect(replyTo.line).toContain('[email protected]');
This verifies that the email that actually arrived contained the expected reply address.
For a repeated field such as Received, use filter():
const receivedHeaders = email.headers.filter(
header => header.key === 'received'
);
You can use the same pattern to test:
Reply-ToList-UnsubscribeList-Unsubscribe-PostMessage-ID- custom transaction headers
- environment headers
- provider-specific metadata
- content-related headers
For SPF and DKIM, testmail.app also exposes parsed authentication results directly on the email object, so you do not need to parse the raw Authentication-Results field yourself.
Test what actually arrived
This is the key difference between testing the email before it is sent and testing the received message.
Your application might create:
X-Environment: production
A unit test proves that your code attempted to send it.
An end-to-end test follows the message further:
Application
↓
Email provider
↓
Mail infrastructure
↓
testmail.app inbox
↓
Assertion
That lets you verify what actually arrived after the message passed through your sending provider and mail infrastructure.
You do not need to assert every header.
Focus on fields that affect your application's behavior, deliverability, debugging, or user experience.
Manual header inspection vs automated testing
Both are useful for different reasons.
Inspect headers manually when:
- debugging a failed email
- investigating a delivery delay
- checking an unfamiliar authentication result
- exploring how your email provider modifies messages
- inspecting a message while developing a new email flow
Test headers automatically when:
Reply-Tomust always use a particular mailbox- unsubscribe metadata must always be present
- a custom transaction ID must survive delivery
- a specific sender identity is required
- authentication behavior should remain consistent
- a regression could silently change message metadata
A useful rule is:
Inspect headers manually to understand a problem. Automate the checks that should never regress.
Email headers vs SPF, DKIM, and DMARC DNS checks
Email headers and DNS checks answer different questions.
Email headers tell you what happened to a particular message.
DNS checks tell you how a domain is configured when you perform the lookup.
For example, a received message might contain:
Authentication-Results: mx.example.net;
spf=fail;
dkim=pass;
dmarc=pass
That tells you what the receiving system reported for that particular email.
You can then inspect the sending IP, SPF identity, and domain's SPF record to investigate why SPF failed.
Similarly, if:
dkim=fail header.d=example.com
appears in the message, the DKIM-Signature can identify the signing domain and selector:
d=example.com;
s=selector1;
You can then check whether the corresponding public key is correctly published in DNS.
When troubleshooting an email that has already been delivered, start with the message headers. Then investigate the underlying DNS configuration if necessary.
Email Headers FAQs
What are email headers?
Email headers are metadata fields that contain information about an email, including its sender, recipients, delivery path, authentication results, message ID, and content type. Email headers are added by email clients and mail servers as a message is created and delivered.
What information is included in an email header?
Email headers can contain information about the sender, recipient, delivery path, authentication, message identification, content type, and other message properties.
Common email headers include:
From: [email protected]
To: [email protected]
Subject: Hello
Message-ID: <[email protected]>
Received: ...
Authentication-Results: ...
Content-Type: ...
What are the most important email headers?
The most important email headers depend on what you're troubleshooting. For general email troubleshooting, the key headers are Received, Authentication-Results, From, Reply-To, Return-Path, DKIM-Signature, Message-ID, and Content-Type.
For application email testing, you may also need to check List-Unsubscribe, List-Unsubscribe-Post, and custom headers used by your application.
How do I read email headers?
To read email headers, start with Authentication-Results when checking email authentication, then inspect Received to trace delivery. Check From, Reply-To, and Return-Path when troubleshooting sender or reply addresses.
For rendering or attachment problems, inspect MIME headers such as Content-Type.
How do I view email headers?
You can view full email headers from most email clients by opening the message's original source or message details.
- Gmail: Select Show original.
- Outlook: Open the message details through More actions > View > View message details.
- Apple Mail: Choose View > Message > All Headers.
If you're testing emails generated by an application, you can also send them to a testmail.app inbox and inspect the headers there.
How do I analyze email headers?
To analyze email headers, check authentication results, trace the Received fields, verify sender and reply addresses, and inspect message identifiers and MIME information.
For authentication problems, start with Authentication-Results. For delivery problems, examine the Received chain. For reply or sender problems, check From, Reply-To, and Return-Path.
How do I trace an email using its headers?
You can trace an email by examining its Received headers from the bottom up. Each Received field represents a mail server or system that handled the message, allowing you to reconstruct its delivery path.
When tracing an email, pay particular attention to which mail systems you trust and whether the information was added by a trusted server.
Why does an email have multiple Received headers?
An email has multiple Received headers because each mail system that handles the message can add its own Received field. These entries create a record of the systems the message passed through during delivery.
Can email headers show the sender's IP address?
Email headers can contain IP addresses associated with message delivery, but they do not necessarily reveal the sender's personal IP address. The addresses shown may belong to an email provider, gateway, proxy, or other mail relay.
What is Authentication-Results in an email header?
Authentication-Results is an email header that records authentication results reported by a mail system. It commonly contains the results of SPF, DKIM, and DMARC checks.
For example:
Authentication-Results:
spf=pass
dkim=pass
dmarc=pass
Only rely on authentication results added by mail systems within a trust boundary you recognize.
How do I check SPF, DKIM, and DMARC in email headers?
To check SPF, DKIM, and DMARC, look for the Authentication-Results header and check whether each authentication method passed, failed, or produced another result.
You may also find additional information in Received-SPF and DKIM-Signature.
Does a DKIM-Signature header mean DKIM passed?
No. A DKIM-Signature header only indicates that the message contains a DKIM signature. To determine whether DKIM authentication passed, check the DKIM result in Authentication-Results.
What is the difference between From, Reply-To, and Return-Path?
From identifies the sender shown to the recipient, Reply-To specifies where replies should be sent, and Return-Path represents the SMTP reverse-path used for delivery and bounce handling.
These headers can contain different addresses and can legitimately be different.
Why should I test the Reply-To header?
You should test the Reply-To header to make sure replies to application-generated emails reach the intended mailbox. An email can render correctly and still have an incorrect Reply-To address.
What email headers should I test?
Test the email headers that affect your application's behavior rather than asserting every header.
Common headers to test include:
FromReply-ToMessage-IDList-UnsubscribeList-Unsubscribe-Post- Custom application headers
- Environment or transaction headers
- Authentication results
The exact headers you need to test depend on how your application sends and processes email.
Can email headers be spoofed?
Yes. Some email headers can be forged or modified by the sender or other systems that handle a message. A From address alone should not be treated as proof of identity.
For authentication and delivery analysis, use trusted routing information and authentication results such as SPF, DKIM, and DMARC.
Does Bcc appear in email headers?
Bcc recipients are normally removed from the message headers before delivery to other recipients. As a result, recipients generally cannot see who was included as a Bcc recipient.
What is a Message-ID header?
Message-ID is an identifier intended to uniquely identify an email message. It is commonly used for message tracking, email threading, log correlation, and troubleshooting.
What are custom email headers?
Custom email headers are application-specific or provider-specific headers used to carry additional metadata with an email.
For example:
X-Environment: staging
X-Transaction-ID: txn_12345
Developers can use custom headers to correlate emails with application activity or identify information such as the environment or transaction that generated a message.
What is the difference between an email header and an email preheader?
An email header contains technical metadata about a message, while an email preheader is preview text that some email clients display alongside or below the subject line.
They serve different purposes: headers provide message and delivery information, while preheader text provides recipients with additional context before they open the email.
Can I test email headers automatically?
Yes. You can test email headers automatically by retrieving the headers from a received email and asserting their values in your automated tests.
With testmail.app, you can retrieve the headers from received test emails through the API and verify them directly in your tests. This lets you test what actually reached the inbox rather than only what your application attempted to send.