Skip to content

Cookie settings

Choose which kinds of cookies you allow. You can change your choice at any time via Cookie settings at the bottom of every page. Privacy statement

Necessary

Always on

Needed to log in, keep your cart and remember your choices. These are always on.

Which cookies?
  • weboke_sessie, weboke_klant, weboke_remember: your session and staying logged in
  • weboke_basket: your cart
  • wkBtwIncl: showing prices with or without VAT
  • wok_cookies: your cookie choice, 12 months

Measures which ad leads to a visit or order, so we do not pay for ads that do nothing.

Which cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), up to 90 days
  • OpenAI Ads, ads in ChatGPT
  • wok_aff: which partner referred you to us (affiliate programme), 60 days

4.6

Country and language

Each country has its own site, with prices and VAT for that country.

View

Module 1 · 1.5

English

Reading headers: where did this email come from?

Module 1: How email works · Reading time: 11 minutes

Learning objective: After this lesson you'll be able to open an email's headers, read the Received lines in the right order, and work out from Authentication-Results whether SPF, DKIM and DMARC passed.

Key terms: headers, RFC 5322, Received, Return-Path, From, Reply-To, Message-ID, DKIM-Signature (d=, s=), Authentication-Results, ARC, X-headers, source or original message

What you normally don't see

Your mail program shows you a few details about an email: sender, subject, date, recipients. In reality, every email has dozens of headers at the top, before the text. They're added by the sender's program and by every server the email touches along the way. Together they form the email's travel log.

If you can read headers, you can answer a lot of questions yourself: is this email really from my bank? Why did it only arrive after two hours? Why did it end up in spam? Is my own DKIM working correctly? Many exercises in this course ask you to look at headers. In this lesson you'll learn how.

Opening headers

Each program has a different button for it:

ProgramWhere
Gmail (web)Three dots on the right of the message, Show original
Outlook (new and web)Three dots, View, View message details
Outlook (classic)Open the message, File, Properties, the "Internet headers" box
Apple Mail (Mac)View menu, Message, All Headers (or Raw Source)
ThunderbirdView menu, Message Source (Ctrl+U)
Roundcube (webmail)Open the message, More, Show source (or Headers)

On a phone this usually isn't possible. In that case, forward the email to yourself as an attachment, or open it in webmail.

An example

Jan receives an email from Anna. Here's what the most important headers look like (shortened):

Return-Path: <anna@example.com>
Delivered-To: jan@example.net
Received: from mx1.mailprovider.example (localhost [127.0.0.1])
        by mailbox3.mailprovider.example with LMTP; Sun, 08 Nov 2026 10:15:09 +0100
Received: from out.hosting.example (out.hosting.example [192.0.2.25])
        by mx1.mailprovider.example with ESMTPS id 4F2A1B
        for <jan@example.net>; Sun, 08 Nov 2026 10:15:07 +0100
Received: from [198.51.100.77] (helo=[10.0.0.12])
        by out.hosting.example with ESMTPSA (TLS1.3)
        (authenticated as anna@example.com); Sun, 08 Nov 2026 10:15:04 +0100
Authentication-Results: mx1.mailprovider.example;
        spf=pass smtp.mailfrom=example.com;
        dkim=pass header.d=example.com header.s=x;
        dmarc=pass header.from=example.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=x;
        h=From:To:Subject:Date:Message-ID; bh=...; b=...
From: Anna <anna@example.com>
To: Jan <jan@example.net>
Subject: Offerte
Date: Sun, 8 Nov 2026 10:15:00 +0100
Message-ID: <a1b2c3@example.com>

Received lines: from bottom to top

Every server that passes the email on adds a Received: line at the top. So the oldest line is at the bottom and the newest is at the top. Read them from bottom to top to follow the journey:

  1. Bottom line: Anna's laptop (IP 198.51.100.77, her home connection) delivers to out.hosting.example, using ESMTPSA (the A stands for authenticated: she logged in) and TLS 1.3. At 10:15:04.
  2. Middle line: out.hosting.example (192.0.2.25) delivers to mx1.mailprovider.example, the MX for example.net. At 10:15:07.
  3. Top line: the mail server places the email internally into Jan's mailbox (LMTP). At 10:15:09.

A Received line always has the form from <who offered it> by <who accepted it> with <protocol>; <time>. In brackets after from is what the receiving server itself observed: the real name (PTR) and the real IP address. That part is reliable, to the extent that you trust that receiving server. What the sender itself claimed (helo=) cannot be verified.

Two practical tricks:

  • Finding a delay: compare the times. If there's a two-hour gap between two lines, the email sat in a queue that long at that point. Watch out for time zones (+0100, +0000).
  • Finding the real sending server: look for the topmost Received line that was written by a server belonging to the recipient itself, and check what's after from there. Everything below that was written by the sending side and could, in theory, be made up. In the example, 192.0.2.25 is the server that delivered to the recipient; that's the one SPF and reputation are judged against.

The addresses

HeaderWhat it isWho sets it
Return-PathThe envelope sender (MAIL FROM, lesson 1.2). This is where bounces go. SPF checks this domain.The receiving server, on delivery
FromThe sender you see. DMARC protects this domain.The sender
Reply-ToWhere a reply goes, if it needs to be different from From.The sender
To, CcThe visible recipients. BCC doesn't appear here.The sender
Delivered-ToThe mailbox the email was actually delivered to (useful with forwarding).The receiving server
Message-IDA unique number for the email. Useful for finding an email again in a log.The sender

A well-known scammer's trick: a From that looks like your bank, with a Reply-To pointing to a completely different address. If in doubt, always check the domain in From and in Return-Path, and look at Authentication-Results.

Authentication-Results: the recipient's verdict

The receiving server records the results of its checks in Authentication-Results (RFC 8601):

  • spf=pass smtp.mailfrom=example.com: the IP of the delivering server is listed in the SPF record of the domain in Return-Path.
  • dkim=pass header.d=example.com header.s=x: the DKIM signature for domain example.com, with key (selector) x, checks out.
  • dmarc=pass header.from=example.com: the domain in From is aligned with a successful SPF or DKIM check, so DMARC passed.

Other results you may see: fail (didn't check out), softfail (SPF ends in ~all and the IP isn't listed), neutral, none (no record), temperror (temporary DNS error) and permerror (broken record, for example two SPF records). What these mean exactly and how to fix them is covered in module 4.

Note: only trust the Authentication-Results from the recipient's own server (the name at the front, here mx1.mailprovider.example). A forged email can include its own, made-up Authentication-Results. Good servers strip these out, but not all do.

DKIM-Signature: the signature

The DKIM-Signature header is the signature itself. You often need two fields from it:

  • d= the domain that's signing (here example.com);
  • s= the selector, the name of the key (here x).

Together these let you find the public key in DNS: x._domainkey.example.com. In exercises and when troubleshooting, you'll often need to look up exactly these two values. An email can have more than one DKIM signature, for example one from your domain and one from the sending service. We'll go into this in more depth in lesson 4.3.

You may also sometimes see ARC-Seal, ARC-Message-Signature and ARC-Authentication-Results. ARC (RFC 8617) is a way for intermediate stops, such as a mailing list or a forwarding server, to record what the checks showed before they changed the email. You don't need to be able to read these yet.

X-headers

Headers starting with X- aren't standardised. Spam filters put their score in them, such as X-Spam-Status: No, score=1.2 or X-Spam-Flag: YES. This helps you see why something ended up in spam. They differ by provider.

Summary

  • Headers are an email's travel log. Open them with "show original", "message source" or something similar.
  • Read Received lines from bottom to top. The line written by the recipient's own server tells you which IP delivered the email.
  • Return-Path is the envelope sender (SPF), From is the visible sender (DMARC), Reply-To is where replies go.
  • Authentication-Results gives the verdict on SPF, DKIM and DMARC; only trust the one from the receiving server.
  • DKIM-Signature contains d= (domain) and s= (selector); together they give the location of the key: s._domainkey.d.

Quiz

1. In which order do you read Received lines to follow an email's journey?



2. Which address does SPF check the domain of?



3. A DKIM-Signature contains d=example.org; s=mail2026. Where is the public key?



4. There's a 3-hour gap between two Received lines. What does this usually mean?



5. An email appears to come from your bank, but Reply-To is a Gmail address and Authentication-Results shows dmarc=fail. What do you conclude?



Exercise

Exercise Z1.5: Having headers parsed. Send yourself an email from a different address (for example, from your work address to your personal address, or the other way round), open the headers, and paste them into the form. If you don't have a second address, use the sample file kopregels-1.txt provided with the exercise. Then fill in yourself: the IP address of the server that delivered to the recipient, the domain in Return-Path, the domain and selector of the DKIM signature, and the SPF, DKIM and DMARC results. The program parses the same headers, looks up the DKIM key live, and places its result next to yours. Your headers are not stored.

Exercise Z1.5: Having headers parsed

File for this exercise: kopregels-1.txt

Paste the headers of an email you sent yourself, or choose the example file. Your headers are only used while checking and are not stored. You may replace addresses in the headers with example.com first.











What you enter and what we find isn't stored. Your browser remembers your answers and whether you've passed the exercise. If you're signed in, we only save that you got the exercise (almost) right in My courses; you can delete that there too.

Further reading

The steps in these articles apply to WebOké's control panels; with other providers it works in a similar way.

One moment…

Set up your domains

For each domain, arrange the nameservers, the link to your hosting and who becomes the owner.

Loading your domains…