Article featured image
How to read email headers: A developer's guide
19min readLast updated: August 26, 2026

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:

  1. Check Authentication-Results for SPF, DKIM, and DMARC.
  2. Read trusted Received headers from bottom to top to trace the delivery path.
  3. Compare From, Reply-To, and Return-Path.
  4. Compare Received timestamps if the email arrived late.
  5. Check Content-Type and other MIME fields for rendering or attachment problems.
  6. 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:

ProblemHeader to inspect or test
Replies go to the wrong mailboxReply-To
Wrong sender identityFrom, Sender
Bounces are handled incorrectlyReturn-Path
SPF or DKIM failsAuthentication-Results
DMARC failsAuthentication-Results, From
Unsubscribe support is missingList-Unsubscribe
One-click unsubscribe is missingList-Unsubscribe-Post
Application metadata disappearsCustom headers
Email cannot be correlated with logsMessage-ID or custom ID
HTML or attachments behave incorrectlyMIME 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:

  • From uses the expected address
  • Reply-To points to the correct support mailbox
  • the expected Message-ID exists
  • a custom transaction header is present
  • List-Unsubscribe exists 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:

HeaderWhat it tells you
FromThe message author or authors
ToPrimary recipients shown in the message
CcAdditional recipients shown in the message
BccBlind-copy recipients during message creation, normally withheld from other delivered copies
SenderThe agent responsible for transmitting a message when different from the author
Reply-ToWhere replies should be directed
SubjectThe email subject
DateThe message's stated origination date and time
Message-IDAn identifier intended to uniquely identify the message
Return-PathThe SMTP reverse-path recorded at final delivery
ReceivedA record of a mail handoff
Authentication-ResultsResults of authentication checks reported by a mail system
Received-SPFInformation about an SPF evaluation
DKIM-SignatureThe message's DKIM signature
MIME-VersionThe MIME version used by the message
Content-TypeThe type and structure of the message content
Content-DispositionHow a MIME part should be presented
Content-Transfer-EncodingHow a MIME part is encoded for transport
In-Reply-ToIdentifies a message this email replies to
ReferencesMessage identifiers used to relate messages in a thread
List-UnsubscribeMethods a recipient can use to unsubscribe
List-Unsubscribe-PostCan indicate support for one-click unsubscribe
Auto-SubmittedIndicates certain automatically generated messages
ARC-*Authentication information carried through intermediaries
Custom headersApplication, 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.

TermWhat it is
Email headerMetadata inside the message, such as From, Subject, and Message-ID
SMTP envelopeDelivery information used during SMTP, including MAIL FROM and RCPT TO
Email bodyThe plain-text, HTML, and attachment content
Email preheaderPreview 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:

  1. Open the email.
  2. Click the three-dot More menu next to Reply.
  3. 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:

  1. Open the email.
  2. Select More actions.
  3. Select View > View message details.

In classic Outlook for Windows:

  1. Open the message in its own window.
  2. Select File > Properties.
  3. 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.

Analysing email headers in testmail.app's visual viewer

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 message
  • with: the protocol or transport used
  • for: 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:

FieldMeaning
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.

FieldPurpose
FromIdentifies the message author shown to the recipient
SenderIdentifies the agent responsible for transmission when required
Reply-ToTells the email client where replies should go
Return-PathRecords the SMTP reverse-path at final delivery
Envelope senderIdentity 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-Unsubscribe exists
  • the expected unsubscribe URL or address is present
  • List-Unsubscribe-Post is 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:

  • Received
  • Authentication-Results
  • DKIM-Signature
  • From
  • Return-Path

Which email header should I check?

You normally do not need to inspect every field.

ProblemStart with
Email took too long to arriveReceived timestamps
Unexpected delivery routeReceived
SPF failedAuthentication-Results, Received-SPF
DKIM failedAuthentication-Results, DKIM-Signature
DMARC failedAuthentication-Results, From, SPF and DKIM identities
Replies go to the wrong inboxReply-To, From
Wrong bounce addressReturn-Path, envelope sender
HTML displays incorrectlyContent-Type, MIME structure
Attachment is missingContent-Type, Content-Disposition
Unsubscribe metadata is missingList-Unsubscribe, List-Unsubscribe-Post
Custom metadata is missingRelevant custom header
Need to correlate with logsMessage-ID or custom transaction header
Need to investigate a delayTrusted 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-To
  • List-Unsubscribe
  • List-Unsubscribe-Post
  • Message-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-To must 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:

  • From
  • Reply-To
  • Message-ID
  • List-Unsubscribe
  • List-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.

Subscribe to blog

Stay updated with our latest insights and curated articles delivered straight to your inbox.