Skip to content
MX Verdict
Tools

Email Header Analyzer

Paste the header of an email to see which servers it passed through, the SPF, DKIM and DMARC results recorded in it, and which fields deserve a second look. Your browser does the analysis; the header is never uploaded.

Paste the full header of a message, or the whole message: only the header section is read. The analysis runs in your browser; the text is not sent to us and not stored.

What this email header analyzer shows

Every email carries a header: lines such as From:, Subject: and Received: above the text of the message. Your mail app shows only a few of them. The rest record the servers the message passed through, what the receiving server found when it checked SPF, DKIM and DMARC, and how spam filters rated the message.

Paste the header, or the whole message, into the box above, or open a saved message file (.eml or .txt). The analyzer lays it out:

  • a verdict built from the results the analyzer takes to be your own mail provider's, DMARC first (how the verdict is made);
  • the route: every Received line in delivery order, oldest first, with the time each step took and what each server wrote about encryption, and the server that most likely handed the message to your provider;
  • From, Reply-To, Return-Path and the other address fields side by side, with the differences that matter;
  • every DKIM signature with its domain, selector and signed fields;
  • the verdicts of Microsoft 365, SpamAssassin and rspamd, where their fields are there and documented;
  • every field as written, and a finding for each point worth knowing, linked to its explanation on this page.

Your header stays on your device. Your browser analyzes the text with the same engine that runs our other checks. What you paste is not sent to our server or anywhere else, is not put into the page address and is not stored. A file you open is read by your browser, and only its header goes into the box. When the page opens, your browser loads the analyzer's program code from this site; that request is the same for every visitor and carries nothing you paste.

The analyzer makes no network requests of its own: it does not look up DNS records or IP addresses. The address of the server that delivered the message and the domains in the header become links to our other checks. A check runs only if you open one of those links, and then only that address or domain, nothing else from the header, is in the address of the page you open.

What it does not do: it does not verify DKIM signatures or repeat the SPF and DMARC checks (it reads the results recorded in the header when the message arrived; see why), and it cannot tell you that a message is safe. It shows which claims in the header the receiving side's results back up and which ones anyone could have written.

One header can be up to 1,048,576 characters long; the other size limits are set well above what the standards expect, an analysis that takes longer than 4 seconds is stopped, and the result says so when either happens.

How to get the header of an email

To check an email header, you first need to get it: mail apps hide the header, but most have a command that shows it. Copy all of it, from the first line down to the first empty line; copying the whole message is fine too, because only the header is read. Use the message you received, not a forwarded copy: forwarding makes a new message with a new header. The steps for Gmail, Outlook, Apple Mail, iCloud Mail and Yahoo Mail are the ones each provider gives in its own help pages, as we read them on September 27, 2026; menus change, so the names may differ slightly in your version.

Gmail

  1. Open Gmail in a browser and open the message.
  2. Next to Reply, click More, then Show original. The full header opens in a new window.
  3. Click Copy to clipboard and paste it into the box above.

Google gives these steps for Gmail in a browser only; for the Gmail app, see headers on a phone.

Outlook, Outlook.com and Microsoft 365

New Outlook for Windows, Outlook on the web and Outlook.com: open the message, select More actions at the top of the message window, then View > View message details, and copy the text it shows.

Classic Outlook for Windows: double-click the message to open it in its own window, then click File > Properties. The header is in the Internet headers box; highlight the text in that box and press Ctrl+C.

Microsoft's help page covers these versions only, not Outlook for Mac. On a Mac, open the same mailbox in a browser instead (a Microsoft 365 work or school mailbox in Outlook on the web, a personal Outlook.com or Hotmail mailbox at Outlook.com) and follow the first steps above.

Apple Mail and iCloud Mail

Mail on a Mac: select the message, choose File > Save As and the format Raw Message Source, which saves it as an .eml file (dragging a message to the desktop does the same). Then open that file on this page with Open .eml or .txt file. These steps are in Apple's Mail guide for macOS 27. To see every header field in the message window, Apple's guide for macOS Sequoia 15 gives View > Message > All Headers; we found no such page in the guides for macOS Tahoe 26 and macOS 27, so we could not check that menu there.

iCloud Mail on the web: go to icloud.com/mail, select the message, select the More button, then Show All Headers.

Messages received in an iCloud mailbox currently get the verdict Unknown: the hand-off search stops on one of iCloud's own lines (see no hand-off).

Yahoo Mail

Open the message, click the More options icon (in the older Yahoo Mail, the More icon) and select View Raw Message. Copy the lines at the top, down to the first empty line, or all of it.

Other mail apps and phones

Look for a command named like Show original, View source, Message source or View raw message, usually in the message's More menu. If your app, on a phone for example, has none, open the same mailbox in a browser on a computer and use the steps above.

How to read email headers

A header is a list of fields, one Name: value each, and it ends at the first empty line; the text of the message follows. A long field goes on over the next lines, which start with a space or a tab. Some names appear many times: Received once for every server.

Most fields are written by the sender's mail program and can say anything: From, Subject, Date. Others are added on the way: Received, Authentication-Results, Return-Path and the spam filters' own fields. Only the ones your own provider added can be relied on; everything else in the header may have been written by the sender.

Received lines: read the route from the bottom up

Every server that passes the message on adds a Received line at the top. RFC 5321, the standard for sending mail, says: “SMTP servers MUST prepend Received lines to messages; they MUST NOT change the order of existing lines or insert Received lines in any other location.” So the bottom line is the first step and the top line the last. Yahoo's help puts it the same way: “The first delivery is at the bottom; the newest at the top.” A made-up line in the format of Postfix, a common mail server:

Received: from out-24.mail.example.com (out-24.mail.example.com [198.51.100.24])
        (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
        by mx1.example.net (Postfix) with ESMTPS id 9B7E21C0031
        for <jane@example.net>; Fri, 25 Sep 2026 14:03:11 +0000 (UTC)
  • from: the server that handed the message over. The standard asks for two things there: the name that server gave for itself, and “an address literal containing the IP address of the source, determined from the TCP connection”. The name after from is whatever the other server said; the address in square brackets (and, in this format, the name next to it, from reverse DNS) is what the receiving server saw itself.
  • by: the server that wrote the line.
  • with: how the message came. RFC 3848 registers the extra letters, and Exim's documentation explains them plainly: “This can be followed by “s” for secure (encrypted) and/or “a” for authenticated.” So ESMTPS or LMTPS says the step used TLS, ESMTPA says the sending side logged in to the server, and ESMTPSA says both; some servers write them in lower case, as Exim does (esmtpsa). Plain SMTP or ESMTP does not say that TLS was used, but the line may still name a TLS version in a comment, like the one in parentheses on the second line here; the analyzer takes either as TLS.
  • id and for: the server's own number for the message and the recipient; after the semicolon, the date and time the server wrote the line.

Go down from the top while the lines are your provider's own: the first line where it received the message from a server outside it is the hand-off. Everything below that line was already in the message when it arrived and may be made up.

Delays and time zones

Each date carries its own offset from UTC. RFC 5322, the standard for the message format: “The zone specifies the offset from Coordinated Universal Time (UTC, formerly referred to as “Greenwich Mean Time”) that the date and time-of-day represent.” Servers in different places write different offsets, so convert every time to UTC before you subtract. In this made-up example the top line looks two hours later than the one below it:

Received: from mx1.example.net (mx1.example.net [10.0.0.25])
        by mail.example.net with LMTP; Fri, 25 Sep 2026 16:03:12 +0200
Received: from out-24.mail.example.com (out-24.mail.example.com [198.51.100.24])
        by mx1.example.net with ESMTPS; Fri, 25 Sep 2026 14:03:11 +0000

16:03:12 at +0200 is 14:03:12 UTC, so the step took one second, not two hours. The analyzer converts every date to UTC and shows the delay of each step. When the time goes back from one line to the next, two servers' clocks disagree, or one of the dates uses a time zone name read as UTC (time going backward). A time zone name it does not know, such as CEST, is read as UTC, as RFC 5322 asks, and the delays next to it are marked uncertain.

The Date field is not a delivery time. RFC 5322 says it “is specifically not intended to convey the time that the message is actually transported”, and Microsoft describes it as “based upon the computer clock on the sender's computer”. A large gap between Date and the lowest, oldest Received line can come from the sender's clock, or from a message written and queued while the sender was offline, rather than from a slow delivery.

Authentication-Results: whose verdict is it?

The receiving server records what it found for SPF, DKIM and DMARC in an Authentication-Results field (RFC 8601). A made-up one:

Authentication-Results: mx1.example.net;
        dkim=pass header.d=example.com header.s=s2026;
        spf=pass smtp.mailfrom=bounces+7421@bounce.example.com;
        dmarc=pass header.from=example.com

The first word, mx1.example.net, is the authserv-id: the name of the system that did the checks. Anyone can write this field, including the sender, so the standard asks mail apps not to act on it “unless the authentication service identifier of the header field is used within the ADMD as configured by the user or administrator”, that is, unless the name is your own provider's. Receiving servers that follow it must delete fields that claim their name but came from outside. The place matters as well as the name: a receiving server adds its field on top of what arrived, so the analyzer uses only the fields above the hand-off line, or, when there are none, the topmost one just below it if its name is your provider's (the overall verdict). Fields with other names above the hand-off line come from another system on your side, such as a filtering service; the fields lower down are earlier checks, by the sender's system or a forwarder, or fields written to look like them (other results). Microsoft's documentation lists what Microsoft 365 writes for each check without such a name (what the analyzer does then).

dmarc=pass means SPF or DKIM passed for a domain that matches the one in From. It shows that the From domain is not forged, not that the message is harmless: RFC 8601 warns that “the existence of this header field indicating a “pass” does not render the message trustworthy.” Anyone can own a domain and pass its checks. How the domains have to match is explained on the DMARC checker page.

DKIM-Signature: who signed it and what it covers

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s2026;
        t=1790344987; h=from:to:subject:date:message-id;
        bh=MADEUPBODYHASH=; b=MADEUPSIGNATURE
  • d=: the signing domain, “The SDID claiming responsibility for an introduction of a message into the mail stream” (RFC 6376). It does not have to be the From domain; DMARC counts it only when it matches.
  • s=: the selector, the name of the key; the public key is published in DNS at s2026._domainkey.example.com for this signature.
  • h=: the fields the signature covers; From must be one of them.
  • bh= and b=: the hash of the body and the signature itself; a=: the algorithm; t= and x=: when it was made and when it expires (seconds since 1970); l=, if present: how much of the body is signed.

The analyzer shows these tags and checks them for known problems, but it does not verify the signature (why). A receiving server that checks DKIM records its verdict as the dkim= result in Authentication-Results.

From, Sender, Reply-To and Return-Path

  • From: in the words of RFC 5322, “The “From:” field specifies the author(s) of the message”. It is the address your mail app shows, and the one DMARC protects.
  • Sender: “the mailbox of the agent responsible for the actual transmission of the message”, for example an assistant who sends mail for someone else.
  • Reply-To: it “indicates the address(es) to which the author of the message suggests that replies be sent”. When you press Reply, your answer goes there, not to From.
  • Return-Path: added by the last server: “When the delivery SMTP server makes the “final delivery” of a message, it inserts a return-path line at the beginning of the mail data.” It holds the envelope sender, where bounces go and whose domain SPF checks. “It is possible for the mailbox in the return path to be different from the actual sender's mailbox”; for mailing lists the standard calls this “common and useful” (what that means for DMARC).

How to check an email header for phishing

When you read an email header for phishing, keep two limits in mind: a header cannot prove that a message is safe, and one unusual field does not prove that it is phishing, because mailing lists, newsletters and forwarding produce many of the same signs. Google says it plainly: “Messages that aren't authenticated aren't necessarily spam.” What a header can show is whether the message's claims about itself are backed by the results your provider recorded. Google advises: “Check the message headers to make sure the “from” header isn't showing an incorrect name”, and Microsoft notes that “By checking the header, you can find out if the email address is different than it appears”. Check these, in this order:

  1. Your provider's DMARC result. dmarc=fail for the domain in From means that neither SPF nor DKIM passed for it (DMARC result). A pass means only that the From domain is not forged; it says nothing about the intentions of whoever owns that domain.
  2. The address behind the name. A mail app may show only the display name. Google's advice: “Check that the email address and the sender name match.” A display name that contains a different address is flagged (display name with an address).
  3. The domain, letter by letter. Microsoft's examples of look-alike domains: “Like micros0ft.com where the second “o” has been replaced by a 0, or rnicrosoft.com, where the “m” has been replaced by an “r” and a “n”.” A domain can also use letters from other alphabets; in the header it is then written with xn-- (Punycode) or in its own letters. Unicode's security standard gives “paypal” written with Cyrillic “а” letters in place of the Latin “a” as an example of two names that look the same. The analyzer shows such a domain in both forms (internationalized From domain), and it flags a character that reverses the order of the text in the display name and invisible characters in the address (hidden characters).
  4. Where replies go. A Reply-To in another domain sends your answer somewhere other than the From address (Reply-To in another domain). The standard defines the field for that, so a different domain is not wrong by itself; look twice when the message asks you to reply with personal or payment details.
  5. The server that handed the message over. The analyzer guesses which server handed the message to your provider (hand-off). Does its name fit the organization the message claims to come from? Either answer proves little: where your provider wrote no reverse DNS name, the name is the one the sending server gave for itself, and a real company may send through a mailing service whose servers carry that service's name. Its address links to the reverse DNS lookup and the blacklist checker. The lines below it are not evidence (why).
  6. Your provider's own filter verdict. Microsoft 365, for example, writes categories such as phishing, spoofing and impersonation into the header (Microsoft 365 fields).

What the header does not show: where the links in the message lead and what its attachments contain. The analyzer does not read the message text at all.

If you think a message is phishing, do not open its links or attachments and do not reply. Report it from your mail app: in Gmail on a computer, open the message, click More next to Reply, then Report phishing; in Outlook for Microsoft 365 and Outlook.com, select the message and choose Report > Report phishing. In the United States, the FTC also asks you to forward phishing email to the Anti-Phishing Working Group at reportphishing@apwg.org and to report it at ReportFraud.ftc.gov.

Reading the result: the verdict and each finding

The result starts with one verdict, a summary of the address fields and a list of findings. Each finding has a status and a link to its explanation below. Note marks an observation without a verdict: it is worth knowing, but it does not make the message better or worse and never changes the overall verdict. After the findings come links to our other checks, the route, the authentication results, the DKIM signatures, the spam filter fields and every field of the header as written. Very long lists are cut on screen, and the result says how many rows are not shown.

The overall verdict: your provider's results, as far as the header shows them

The verdict comes only from the Authentication-Results fields the analyzer takes to be your provider's. Normally those are the fields above the hand-off line: the topmost one and the others written there under the same domain. Two cases are stricter. If the search went past a line before it found the hand-off or stopped, taking it as one of your provider's own servers, a hop of a private network, a connection within one machine or a line that records no connecting server, the hand-off guess may have landed on a line the sender wrote, because nothing in such a line proves who connected: then only fields above that line count, and if there are none, only the topmost field and those of its domain right under it, with no Received line between them. If no field is above the hand-off line, only the topmost one just below it counts, and only when its authserv-id is in your provider's domain; fields of the same authserv-id right under it can only lower the verdict: a dmarc=fail among them makes it a Fail, and together with them the topmost field can become a Fail or a Warning, never a Pass. Without a hand-off line, only fields above the line where the search stopped count, and the rule for a line the search went past applies to them too; if the search did not stop, only fields above the topmost Received line count; with no Received line at all, the topmost field and the others under its domain count, wherever they sit.

The header cannot prove who wrote them (why): if your provider writes no SPF, DKIM or DMARC result of its own anywhere in the header, a field the sender put where your provider's would be is read as your provider's. Two narrower cases are left as well: a provider that writes its SPF result only in Received-SPF, when the sender's field repeats that result; and Proton Mail's fields at the end of the header when they hold no DMARC result (Proton wrote its DMARC result first in every real header we have seen). When several fields are taken from right under one another, a Pass counts only if the fields read from the top down give it at every step, because a sender can add fields only below your provider's; a provider that writes one field per check may then get an Unknown when its topmost field alone gives no Pass. If a field under your provider's name also sits at the end of the header, below the last Received line, where some filters add theirs (rspamd does by default), including when the message has no Received line of the sender's own, a field just below the hand-off line, or below a line the search went past, gives no Pass: the header does not show which of the two your provider wrote. So does a Received-SPF your provider wrote above such a field with an SPF fail or softfail the field does not repeat. Missing data never gives a Pass.

  • Pass: your provider recorded dmarc=pass for the From domain. Without any DMARC result, the verdict also passes when SPF passed for the envelope sender (smtp.mailfrom) or DKIM passed, for exactly the domain in From.
  • Fail: your provider recorded dmarc=fail, or it recorded no DMARC result and neither SPF nor DKIM passed while at least one of them failed (a softfail counts).
  • Warning: dmarc=none (or Microsoft's dmarc=bestguesspass): the From domain publishes no DMARC policy, so it asks receivers for no protection against spoofing. When the From “domain” is one name without a dot that is not a top-level domain (such as nfeeletronica241194), the verdict is also Warning, and the text says that no policy can exist for it: it is not a domain on the internet.
  • Unknown:
    • nothing could be read, or there is no Authentication-Results, or the analysis took longer than 4 seconds and was stopped (time limit);
    • every one of them was already in the message before your provider accepted it, or sits below the line where the hand-off search stopped, or, without a hand-off line, none sits above your provider's topmost Received line;
    • the only step in the Received lines is an authenticated submission, as in a copy from your Sent folder (no hand-off);
    • no field sits above the hand-off line, and the topmost one just below it names no authserv-id, or one outside the domain of your provider's servers;
    • fields taken as your provider's disagree with each other (conflicting results), the topmost of several fields taken from right under one another give no Pass on their own, a field of the same authserv-id below the line the search went past disagrees with the fields used, or the Received-SPF above them records an SPF fail or softfail they do not;
    • a field under your provider's name sits just below the hand-off line, or below a line the search went past, and another at the end of the header, or Proton Mail's fields under the last Received line give a Pass only together, not in the first of them (whose results);
    • your provider passed the message on inside itself, and its record of the message's earlier entry says DMARC did not pass for the From domain, or the header keeps no such record (the hand-off);
    • part of a field taken as your provider's does not read as results, or names a method outside the IANA registry (Microsoft's compauth, Google's dara and bimi aside): a quoted envelope address written into a comment unescaped could add a result there;
    • the header has no From field, several From fields, or From addresses in more than one domain or without a valid domain (one with characters no domain name has, such as % or a quote, counts as none, and so does an address found only inside encoded text: why), which RFC 9989 leaves outside DMARC; or your provider's DMARC result names another domain in header.from; or the From domain is one name without a dot that is not a top-level domain and the results say Pass;
    • DMARC ended in an error (also one Microsoft 365 writes in action=) or an unregistered value;
    • your provider recorded no SPF, DKIM or DMARC result at all;
    • SPF or DKIM passed, but only for another domain, even a subdomain of the From domain: whether such domains match needs a DNS lookup, which this page does not make;
    • the results say Pass, but the address your provider recorded for the connection belongs to a Received line above the guessed hand-off or above the line where the search stopped (a different address);
    • the results do not settle it, for example a temporary error only.

The verdict is about who sent the message, as far as your provider could check it. It is not a spam score and not a judgment on the content. When results decided it, the line next to the verdict shows them and who wrote them; a Pass taken from a field just below the hand-off line also says that a field the sender wrote would look the same there.

Reading the pasted text

Nothing to analyze. The box was empty or held only spaces. Paste the header and the result appears.

Not an email header. None of the lines looks like a header field: a name, a colon and a value, such as Subject: Hello. That happens when the copied text is the message without its header, or a page that shows the header in another form. Copy it again with the steps above.

The message text was not read. The header ends at the first empty line; RFC 5322 says the body “is separated from the header section by an empty line”. Everything after that line is the body and is not read, so pasting a whole message is fine. If your copy has an empty line in the middle of the header, the fields after it are taken for the body: remove that line and the analyzer reads them.

Lines that are not header fields. Some lines are neither Name: value nor the continuation of a field (which starts with a space or a tab). They are skipped, counted and listed in the result. If the header was copied from a formatted page, a line break or a leading space may have been lost; copy it again from the “original” or “source” view of your mail app.

An indented first line. A first line that starts with a space or a tab and then a field name is read as that field: the first line cannot continue a field, and a copy from a web page can keep its indent. When no line of the header starts at the left edge, the whole block was indented: that indent is removed from every line that starts with it, continuation lines keep the rest of theirs, and a line with nothing left is the empty line that ends the header. The result notes either case.

The analyzer stopped on an error. That is our bug, and the result is Unknown: nothing is reported for this text, and it says nothing about the message. If you can, tell us at the address at the bottom of the page which provider the message came from; please do not send the header itself unless we ask.

Size and time limits

A header comes from outside, and whoever wrote it can make it as long and as odd as they like. So the analyzer has limits on what it reads, set well above what the standards expect: RFC 5322 allows 998 characters in a line, and RFC 5321 asks servers that detect loops by counting to allow “normally at least 100 Received entries”. When one is reached, the result says so, is marked incomplete, and shows exactly what was read:

  • header text: 1,048,576 characters; the lines after that are not read;
  • fields: 2,000; the rest are counted, not read;
  • Received lines: 200, the topmost ones, which include your provider's; the older ones are counted, not read, and the lines that are read keep their numbers in the whole route;
  • one line: 16,384 characters (the standard allows 998); the rest of the line is cut off;
  • a field with RFC 2047 encoded words: 65,536 characters; a longer one is shown as written, not decoded;
  • From, Sender or Reply-To: 65,536 characters; a longer one is not read as addresses at all, so a From that long has no address;
  • To and Cc together: 65,536 characters; the addresses after that are not read, and the numbers of recipients count only those that were.

The analysis runs in a separate worker of your browser, so the page stays responsive while it works, and it is stopped if it takes longer than 4 seconds. A stopped analysis reports nothing about the text: the result is Unknown, not read in full. Every hostile text we know of is read in well under a second; the limit is there for the ones we do not know. If your browser cannot start the worker, the analysis runs on the page itself, without the time limit.

Missing, repeated or unreadable fields

From: missing, repeated or without an address. RFC 5322 requires exactly one From field with a readable address. When it lists several addresses, a Sender field must name the mailbox that sent the message. If you pasted only part of the header, a missing From is expected. In a complete header, a missing or doubled From breaks RFC 5322, and Gmail refuses such mail (what to fix). A missing or second From, From addresses in more than one domain, or a From without an address, also make the overall verdict Unknown.

Fields that may appear only once. Date, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To, References and Subject may each appear at most once (RFC 5322 §3.6). The result names the repeated ones and shows every copy; which copy a mail app displays is up to the app.

Date: missing or unreadable. Every message needs one Date field in the format of RFC 5322, and the day of the week, if given, “MUST be the day implied by the date”. A missing or unreadable Date, or a wrong weekday, breaks RFC 5322. The delays in the route do not depend on it.

No Message-ID. RFC 5322: “every message SHOULD have a “Message-ID:” field.” Replies refer to it in their In-Reply-To and References fields, and Gmail refuses mail without it (what to fix).

The server that handed the message to your provider

The analyzer guesses it from the Received lines, like this:

  1. It reads the lines from the top down. The server names after by are your provider's; their registrable parts (example.net for mx1.example.net) make up its domains. Microsoft names its own servers under outlook.com, office365.com and exchangelabs.com, so when one of them is among these domains, all three are.
  2. The from server of each line is named by what your provider's server found by reverse DNS where it wrote that, otherwise by the name the other server gave for itself (its HELO name, which it can choose freely).
  3. The first line whose from server has a public IP address and a name outside those domains, or no domain name at all, is the hand-off.
  4. Lines between your provider's own servers are passed over, and so are lines from a private address that your provider's server either named by reverse DNS under a private network (such as a name under .internal) or recorded without any name, and lines from a loopback address (127.0.0.1), such as a server passing the message to a content filter on the same machine and back. Lines that record no server handing the message over are passed over too: a program on the same machine handing the message to the server (Exim writes a login name there), a line that names no connecting server at all (Received: by … with no from), and a mail program such as fetchmail that collected the message from your mailbox (recognized only in fetchmail's own form, with its name after the protocol); the mailbox server it names then counts as your provider's. When every server with a public address belongs to your provider (a message sent within it), the lowest of them is shown.
  5. A line that records only a private address, or no address, for a server whose name is not under a domain of the receiving servers named in it or above it ends the search when that name is under a public domain or only the name the server gave itself: the public address is not in the header, and the lines below it could have been written by the sender (no hand-off). A line whose with word says that the sending side logged in (ESMTPA, ESMTPSA) is where a mail program submitted the message to its own server, not a hand-off: the search ends there. If every line above it belongs to that same server, the header shows only the sending side and no result decides the verdict.

It is a best guess, not a certainty: a sender can name itself after your provider; a provider whose servers use several domains can move the guess to one of its own servers; and when your provider's server sits behind a proxy, its line may not show the address that really connected, so the guess can land on a line the sender wrote, and results the sender wrote can then decide the verdict if your provider wrote none of its own above that line. Where your provider wrote the connecting address itself, the analyzer compares the two (a different address).

When your provider passed the message on inside itself (a group or list it hosts, a forwarding rule, or another organization on the same service), the hand-off is the line its own Received-SPF names, and the verdict uses what it recorded at that last step. If it kept a record of the message's earlier entry (ARC-Authentication-Results, X-Original-Authentication-Results or X-MS-Exchange-Authentication-Results) with a DMARC result other than pass for the From domain, the verdict is Unknown: the pass may describe the re-sent message, not its original sender. If the header keeps no such record at all, the verdict is Unknown too, for the same reason.

For the same reason the analyzer notes the topmost line it passed over. Nothing in that line proves who connected: the name may be the one the server gave itself, the header does not show whether your provider checked a reverse DNS name against the address, and a private or loopback address may be a proxy's. So the Authentication-Results below that line are used only as the overall verdict describes.

The address links to the reverse DNS lookup and the blacklist checker; nothing is looked up until you open a link. Addresses reserved for documentation, like those in our made-up sample, get no links: the result says it is an example header.

A different address in your provider's own fields. Some providers write the address that connected to them into another field: client-ip in Received-SPF, or CIP in Microsoft's X-Forefront-Antispam-Report. When it differs from the hand-off guessed from the Received lines, the guess may be wrong. Check both: such a field is one your provider writes, but one placed just below the hand-off line, or, for CIP, below the last Received line, could also have been written by the sender. Fields that may not describe the connection to your provider are left out of this comparison: a Microsoft report marked with a direction other than inbound (DIR:INB), such as DIR:OUT (an outbound message) or DIR:INT (an internal one), a Microsoft report below the hand-off line when none of your provider's servers is Microsoft's, and a client-ip below the hand-off line that is the address of a Received line further down. When the address your provider recorded (client-ip in a Received-SPF above the hand-off line or above the line where the search stopped, or CIP) is that of a Received line above that line, the search went past the line your provider recorded as the connection, and the fields taken as its own may be the sender's: a Pass then becomes Unknown. Any other difference is a Note.

No hand-off server found

There are Received lines, but the server that delivered the message cannot be named, for one of three reasons.

  • None of the lines names a server with a public IP address. The header may be cut, or the message went only between internal servers. Without a hand-off line the analyzer cannot tell which results were written after the message arrived, so it uses only the Authentication-Results above the topmost Received line; when there are none, the verdict is Unknown.
  • One of your provider's lines records only a private address, or no address, for a server whose name is not under a domain of the receiving servers named in it or above it, and that name is under a public domain or only the name the server gave itself; a proxy or load balancer in front of the receiving server can cause that. Everything below that line may have been written by the sender, so nothing below it is used for the verdict, and the lines are marked unproven. Some providers' own internal lines look like this too: in real headers from iCloud and Fastmail, and in some from the kernel.org mailing lists (checked 2026-09-27), the search stops on the provider's own line, so their messages get Unknown even though the provider's results are in the header. Runbox's internal lines stop the search the same way.
  • The search reached a line that records an authenticated submission (with ESMTPSA or ESMTPA): a mail program logged in to hand the message to its own server. When no line above it shows a server receiving the message from another one, as in a copy from your Sent folder, the header shows only the sending side, and no Authentication-Results decides the verdict. When your provider's lines above it name no server that handed the message over, that line ends the search like the line in the second case.

Lines below the hand-off

These lines were already in the message when your provider accepted it. They may be genuine, but nothing proves it: the sender can write any Received lines into a message. RFC 5321 warns that “it is feasible for even fairly casual users to negotiate directly with receiving and relaying SMTP servers and create messages that will trick a naive recipient into believing that they came from somewhere else.” Their addresses are shown, not linked.

Encryption on the route. A step shows as encrypted when the server that wrote the line recorded TLS: a TLS version or cipher, or a with word with the S that RFC 3848 registers for STARTTLS (ESMTPS, ESMTPSA). Otherwise the route says “encryption not recorded”. That does not show that the step was unencrypted: some receiving servers offer TLS and still write ESMTP on every line, and some record TLS in another field (Mail.ru writes X-Mru-TLS). So the analyzer makes no finding about it.

Received lines: none, unreadable, or time going backward

No Received lines. Either only part of the header was pasted, or the message never passed between mail servers, for example a draft or a copy saved by the sender's own app. Copy the full header of a message you received. Without these lines the analyzer cannot tell which Authentication-Results your provider wrote: it uses the topmost one and the others under its domain, wherever they sit.

Received lines that could not be fully read. A line in a format the analyzer does not know is shown as written, and the hand-off is looked for only among the lines it could read. A line without a date, or with a date that cannot be read, gets no delay, and neither does the line above it. The finding itself does not change the verdict.

Time going backward. A step with a negative delay means the clocks of two servers disagree, or, when the delay is marked “about”, that one of the two dates uses a time zone name the analyzer reads as UTC (delays and time zones). The delay is shown as computed, not set to zero, and it does not change the verdict.

No results from your provider

No Authentication-Results. The header has no Authentication-Results field, so your provider's SPF, DKIM and DMARC results are not in it and the verdict is Unknown. Check that you copied the whole header. Not every receiving server writes this field: RFC 8601 gives three possible reasons, that the checks were not available at delivery, that the server offers no such service, or that it does not follow the standard.

Only results from before the hand-off. Every Authentication-Results field sits lower in the header than the Received line just under the hand-off line: it was in the message before your provider accepted it, written by the sender's system or by anyone. It is not your provider's verdict, so the overall verdict is Unknown. If the hand-off guess is wrong, this is wrong too; the route shows which line was taken. Below the line where the hand-off search stopped, a field may also be your provider's own; the header does not show which, so it is not used either. When the search neither found a hand-off line nor stopped, the finding says that no field sits above your provider's topmost Received line, so none of them can be shown to be your provider's; when the only step in the Received lines is an authenticated submission, no field is used at all (why).

Whose results the verdict uses

The finding names the authserv-id of the results the verdict was taken from. Trust them only if that is your own mail provider. If the name is outside the domain of the servers that received the message, the finding says so. Microsoft's documentation lists what Microsoft 365 writes for each check and names no authserv-id; for a field without one, the finding says that the text does not name who wrote it. A field written entirely in encoded words (RFC 2047) is decoded before it is read, and the finding says so.

Which fields count as your provider's depends on where they sit. RFC 8601 says a server that adds this field should put it on top: it “SHOULD be inserted above any other trace header fields such MTAs might prepend. This placement allows easy detection of header fields that can be trusted.” So when there are Authentication-Results above the hand-off line, only those are used: if the hand-off is guessed right, nothing the sender wrote can be above your provider's own line. Some providers write their results just below that line instead. Then only the topmost field there is used for the results, only if its authserv-id is in your provider's domain (the fields of the same authserv-id right under it can still lower the verdict, never give a Pass: the verdict), and the finding says that a forged field placed right under your provider's line would look the same: the analyzer cannot tell them apart. Only your provider can: RFC 8601 requires a server that follows it to delete any field that claims its name but “did not come directly from another trusted MTA.” A provider that does not follow it leaves such a forgery in place, and then the verdict can be wrong. Below a line the hand-off search went past, your provider's fields and a forged field placed right under them look alike too; there a Pass counts only if the fields read from the top down give it at every step, and a field of the same authserv-id further down that disagrees takes the Pass away.

Proton Mail writes its Authentication-Results either above its own Received line or right under the last Received line at the top of the header. When the hand-off line is a Proton Mail server's (protonmail.ch), nothing is written above it and no other field under Proton Mail's name sits anywhere below it, the fields right under the last Received line are read as Proton's; a Pass needs the first of them to give a Pass on its own.

Conflicting results. The results taken as your provider's give different answers to the same question, in one field or in two: different dmarc= results or header.from domains; different spf= results or domains for the envelope sender (smtp.mailfrom), or for the HELO name (smtp.helo); or, in two fields, different dkim= results for the same signing domain. One receiving server does not record two answers for one message, so one of them may have been written by someone else. The analyzer does not pick one: the finding and the overall verdict are Unknown, and the fields are listed. An SPF result for the HELO name is a separate check and does not conflict with one for the envelope sender.

Other Authentication-Results. Fields written under another authserv-id, and every field that the rules above leave out, even when it carries your provider's name, are listed but not used for the verdict. Those above the hand-off line, and above any line the search went past, were written on your side after the message arrived, for example by a filtering service. Those lower in the header are earlier checks or claims: by the sender's own system, a forwarder, a mailing list, or anyone. Two kinds may also be your provider's own: a field below a line the search went past, written by a server that handled the message first, and, just below the hand-off line, a field with the same authserv-id right under the one used, since some servers write one field per check. A field under your provider's name at the end of the header, below the last Received line, may be your provider's too: some filters add theirs there. The header cannot show which, so such fields with your provider's authserv-id never give a Pass, though they can still take one away or lower the verdict, as the overall verdict describes; the finding and the field's label then say that it did.

DMARC result

DMARC passes when SPF or DKIM passed for a domain that matches the From domain. pass is Pass and fail is Fail; what your provider then did with the message depends on the domain's policy and its own rules. none is a Warning: the domain has no DMARC record. Microsoft 365 writes bestguesspass when there is no record but, in Microsoft's words, “If the domain had a DMARC TXT record, the DMARC check for the message would pass.” An error (temperror, permerror) or an unregistered value is Unknown. Microsoft 365 writes a DMARC error in action= next to the result (action=permerror, action=temperror); Microsoft describes permerror as “A permanent error occurred during DMARC evaluation, such as encountering an incorrectly formed DMARC TXT record in DNS.” The analyzer treats that as Unknown too. Some receivers (rspamd, and Gmail in the headers we checked) write the organizational domain in header.from, such as netflix.com for a From address at account.netflix.com, although the IANA registry defines header.from for DMARC as the domain portion of the From header field. Such a result counts for the From domain when header.from is the From domain or a parent of it within the same registered domain (by the Public Suffix List, its private section included), and the result names the From domain; a parent above that, such as a public suffix or a shared hosting domain like github.io, does not count. A result whose header.from names any other domain is not about the From address, so it is Unknown as well. For your own domain, see how to fix it.

No DMARC result. Your provider recorded SPF or DKIM but no dmarc= result; it may not check DMARC. The verdict then passes only when SPF or DKIM passed for exactly the From domain. A pass for a subdomain or the parent domain may count for DMARC, but deciding that needs DNS lookups that this page does not make, so it stays Unknown.

SPF result

SPF checks whether the sending server may send for the domain of the envelope sender (smtp.mailfrom, the Return-Path), or of the name the server gave when there is none. It is not the From domain. pass is Pass; fail is Fail; softfail, neutral, none and policy are Warning; temperror and permerror are Unknown. When your provider recorded both, the finding shows the result for the envelope sender, which the verdict uses, and names the one for the HELO name (smtp.helo) after it. For DMARC, an SPF pass counts only when that domain matches the From domain (Return-Path in another domain). Yandex writes the envelope sender as smtp.mail, a name the IANA registry of Authentication-Results properties does not list; when the result's own comment names the same domain (“domain of … designates”), the analyzer reads it as smtp.mailfrom.

DKIM result

One result per signature, with the signing domain (header.d). One passing signature is enough for Pass; otherwise a failing one gives Fail, an error Unknown, and none (no signature), neutral or policy a Warning. For DMARC, a pass counts only when the signing domain matches the From domain (signature by another domain).

ARC: the result and the sets in the header

ARC (RFC 8617, an experimental protocol, not a standard) lets forwarders and mailing lists pass on the results they saw before they changed the message. arc=pass (Pass): the message carried an ARC chain that validated; arc=fail (Fail): the chain failed; arc=none (a Note): there was none, which is normal for mail that was not forwarded. Any other value is Unknown. Google explains how Gmail uses it: “If a forwarded message passes SPF or DKIM authentication, but ARC shows it previously failed authentication, Gmail treats the message as unauthenticated.”

ARC sets in the header. Each forwarder that uses ARC adds a numbered set of three fields: ARC-Authentication-Results, ARC-Message-Signature and ARC-Seal. The result lists the sets and the cv= value of the latest seal. The signatures are not verified here. It is a Warning when the sets are incomplete or not numbered 1, 2, 3…: “Valid ARC Sets MUST have exactly one instance of each ARC header field (AAR, AMS, and AS) for a given instance value and signing algorithm.”

Microsoft 365 composite authentication

Microsoft 365 adds compauth= with a three-digit reason: “Microsoft 365 combines multiple types of authentication (SPF, DKIM, and DMARC) and other parts of the message to determine whether the message is authenticated.” The finding gives Microsoft's own text for the reason code. pass is Pass, fail Fail, softpass a Warning and none or any other value a Note. It does not decide delivery on its own: “Despite a compauth failure, the message might still be allowed if other assessments don't indicate a suspicious nature.”

DKIM signatures: listed, not verified

The result shows every signature with its tags (what they mean). Checking one needs the public key from DNS and the unchanged message body, and this page reads neither (why). Your provider's verdict is the dkim= result in Authentication-Results.

No DKIM signature. The message was not signed with DKIM, or the signature was removed on the way. For your own domain, see how to turn it on.

Problems in a DKIM signature

From is not signed. The h= list of a signature does not include From. RFC 6376: “If the “h=” tag does not include the From header field, the Verifier MUST ignore the DKIM-Signature header field and return PERMFAIL (From field not signed).” Such a signature counts for nothing, so this is a Fail.

Only part of the body is signed. The signature has an l= tag, so text can be added after the signed part without breaking it. RFC 6376 §8.2: “Use of the “l=” tag might allow display of fraudulent content without appropriate warning to end users.” Google's advice to senders is short: “Do not use the DKIM length tag (l=) in message headers. This tag makes messages vulnerable to spoofing.”

A signature with rsa-sha1. RFC 8301 retired this algorithm: “rsa-sha1 MUST NOT be used for signing or verifying.” Such a signature counts as failed, so this is a Fail. The signer should switch to rsa-sha256.

Signature time: expired or in the future. A signature can carry the time it was made (t=) and an expiry (x=). The analyzer compares them with the time your provider received the message: the date of the hand-off line, otherwise the topmost dated Received line, otherwise the Date field. Expired before that time is a Warning; made after it is a Note: the signer's clock may be off. A signature above the hand-off line was added on your provider's side after the message arrived, so its time is not compared.

A malformed signature. A required tag is missing (v, a, b, bh, d, h, s), v is not 1, the algorithm is unknown, x= is not later than t=, i= is outside the d= domain, or a tag cannot be read. RFC 6376 is strict here: “any inconsistency or unexpected values MUST cause the header field to be completely ignored and the Verifier to return PERMFAIL (signature syntax error).” It is a Warning, not a Fail, because a header copied from a web page can break a signature's tags on the way.

Signed by another domain

No signature is by the From domain or a domain under the same registered name. The message may still be genuine: a sending service may sign with its own domain until DKIM is set up for yours. But DMARC counts DKIM only when the signing domain matches the From domain, so these signatures do not help it pass.

One-click unsubscribe

Checked only when the message has a List-Unsubscribe-Post field. It is a Pass when the parts of RFC 8058 that a header shows are there: the field says exactly List-Unsubscribe=One-Click, List-Unsubscribe has an https address (“MUST contain one HTTPS URI”), and a DKIM signature lists both fields in h=. Otherwise it is a Warning that names what is missing. RFC 8058 also requires that signature to be valid; the analyzer does not verify it, and a signature that cannot pass (rsa-sha1, From not signed, malformed) does not count here.

A display name that contains an address

The name shown before the address contains a different address, as in the made-up "support@example.com" <notice@example.net>. Mail apps that show only the name show the wrong address. Names written in encoded form (RFC 2047) are decoded first, because, as that standard notes, “It is therefore possible to hide ‘special’ characters in encoded-words”. Full-width characters, such as @ in place of @, are read as their plain forms (Unicode normalization NFKC) before the name is searched.

An address hidden in encoded form. A From field that is only RFC 2047 encoded text can decode to a name and an address, such as Support <support@example.com>. That address is not the sender's: RFC 2047 says an encoded word “MUST NOT appear in any portion of an ‘addr-spec’”. A mail app that decodes it may show it as the sender; the analyzer names it and reads the From field as having no address, so the verdict is Unknown. The same goes for Sender and Reply-To.

Hidden characters in From

The From field contains an invisible character that an address or a display name should not contain. A right-to-left override (U+202E) in a display name can make an app draw the text after it in reverse order, so that a name written as moc.elpmaxe@troppus after it reads as support@example.com. Unicode's email security profile rules such characters out of display names, “since the bidirectional controls could influence the ordering of characters outside the quotes”, and says that “bidirectional controls and other format characters are specifically disallowed in the local-part” of an address; a zero-width space (U+200B) is one of those format characters. The finding names each character by its code point. Everywhere the result shows text from the header, the subject included, a bidirectional control is shown by its code point, such as [U+202E], instead of being obeyed; other invisible characters in the address are named in the finding only.

Internationalized From domain

The From domain is written in Punycode (labels starting with xn--) or in Unicode letters. The analyzer shows both forms. Letters from other alphabets can look exactly like Latin ones, so check that the Unicode form is the domain you expect. A label that starts with xn-- but is not valid Punycode, or decodes to plain ASCII, to nothing, or to text with an invisible character such as a zero-width space (U+200B), is named as such and not converted: RFC 5890 calls such labels “Fake A-labels”.

Reply-To, Return-Path, Sender and Message-ID that differ from From

Reply-To in another domain. Replies go to a domain other than the From domain (not counting subdomains of the same registered name). RFC 5322 defines Reply-To for this: it “indicates the address(es) to which the author of the message suggests that replies be sent”. A different domain is not wrong by itself; it matters when a message that claims to be from one organization asks you to reply with personal or payment details.

Return-Path in another domain. Bounces go to a domain other than the From domain. That is not suspicious by itself: RFC 5321 notes that the return path can differ from the sender's mailbox, “for example, if error responses are to be delivered to a special error handling mailbox rather than to the message sender.” It matters for DMARC: SPF checks this domain, and an SPF pass counts only when it matches the From domain. For your own mail, see aligning the bounce domain.

Sender differs from From. A Sender field names the mailbox that sent the message for the author in From. RFC 5322's own example: “if a secretary were to send a message for another person, the mailbox of the secretary would appear in the “Sender:” field”. It is a Note, not a warning.

Message-ID from another domain. The Message-ID was created under a domain other than the From domain (not counting subdomains of the same registered name). RFC 5322 suggests putting there “the domain name (or a domain literal IP address) of the host on which the message identifier was created”, so a message built by a sending service can carry the service's domain. It is a Note, not a warning.

How to fix what the header shows about your own mail

If the header is from a message your domain sent, most findings point to a setting you can change. Send a message to a mailbox at another provider, get its header, paste it here, and work through the findings:

  • DMARC fail or none, SPF or DKIM failing. Publish one SPF record that lists every service that sends for you, turn on DKIM signing at each of them, then publish DMARC. The steps are in the email deliverability check; for Google Workspace, Microsoft 365 and sending services, see the DMARC checker.
  • SPF passes only for the service's domain (Return-Path in another domain). Where your sending service offers a custom bounce or MAIL FROM domain under your domain, set it up, so SPF matches too; DKIM with your domain is the better fix (how to fix sources that fail DMARC).
  • DKIM signature problems (rsa-sha1, an l= tag, From not signed, a malformed tag). These are settings of the program or service that signs. Change them, or ask the service; a new key pair comes from the DKIM generator.
  • Missing Date or Message-ID, a doubled From, incomplete one-click unsubscribe. The program that builds your messages adds these fields; the fix list of the deliverability test explains each.
  • The sending server's address. Open the links next to it: the reverse DNS lookup shows how to set up a PTR record, and the blacklist checker how to get off a list.

Then check the result with a real message: the deliverability test on our home page gives you two addresses to send one message to and checks the message that arrives.

Spam filter headers: Microsoft SCL, BCL and SFV, SpamAssassin and rspamd

Spam filters record their verdict in fields of their own. The analyzer interprets only fields whose meaning the vendor documents (for rspamd, its documentation and published source code), and only in the documented form; everything else is shown as written. A verdict field above the hand-off line was added after your provider accepted the message. One that sits between two Received lines from before the hand-off was most likely already in the message when your provider accepted it. Right under the hand-off line, or below the last Received line, the header does not show who wrote it: the receiving side's filter can put its fields there (rspamd adds them at the end of the header unless it is set up otherwise), and so can the sender. When the analyzer finds the hand-off line, the result says which of these it is. We found no Google documentation of a spam verdict field in Gmail headers, so none is interpreted for Gmail.

Microsoft 365: X-Forefront-Antispam-Report and X-Microsoft-Antispam

“In all organizations with cloud mailboxes, Microsoft 365 scans all incoming messages for spam, malware, and other threats.” The results go into two fields. X-Forefront-Antispam-Report is a list of KEY:value pairs separated by semicolons:

  • SFV, the spam filtering verdict: SFV:NSPM “Spam filtering marked the message as nonspam and the message was sent to the intended recipients.”; SFV:SPM “The message was marked as spam by spam filtering.” SKB, SKS and BLK mean the message was marked as spam or blocked by a blocked sender or domain list, by a mail flow rule, or by a spam decision from on-premises Exchange; the other values say that filtering was skipped or the message was allowed, and why.
  • CAT, the category of threat policy applied, such as PHSH (phishing), SPOOF, BULK or SPM. SRV:BULK: “The message was identified as bulk email by spam filtering and the bulk complaint level (BCL) threshold.”
  • SFTY: “The message was identified as phishing”, with 9.19 for domain impersonation, 9.20 for user impersonation or 9.25 for the first contact safety tip, which “might be an indication of a suspicious or phishing message”.
  • SCL, the spam confidence level: shown, never used as the verdict. Microsoft says that “the SCL value no longer holds the same meaning in cloud organizations”: there it “doesn't determine whether spam filtering identifies a message as Spam or High confidence spam” and “doesn't determine the action taken on the message.” X-MS-Exchange-Organization-SCL is shown the same way and never used as the verdict: “The main purpose of the SCL value is to support on-premises Exchange servers”.
  • CIP, H, PTR, CTRY: the connecting address, its greeting, its reverse DNS name and country. CIP is compared with the hand-off when the report is marked inbound (DIR:INB) or not marked at all (a different address).

SFV:SPM, SKB, SKS or BLK, SRV:BULK, any category from Microsoft's table or any SFTY value makes the finding a Warning.

In X-Microsoft-Antispam, BCL is the bulk complaint level: 0, not from a bulk sender; 1 to 3, a bulk sender with few complaints; 4 to 7, a mixed number of complaints; 8 and 9, a high number. In the default and new anti-spam policies the threshold is 7, and messages that meet or exceed it are treated as bulk; the analyzer marks those as a Warning. Microsoft's preset policies use 6 (Standard) and 5 (Strict), and an organization can set its own, so the default is only a guide.

Other keys in these fields are, in Microsoft's words, “used exclusively by the Microsoft anti-spam team for diagnostic purposes”; they are shown as undocumented, and so is CAT:NONE, which Microsoft's table does not list. For the compauth result, see Microsoft 365 composite authentication.

SpamAssassin: X-Spam-Status and X-Spam-Flag

SpamAssassin's default header is X-Spam-Status: Yes, score=… required=… tests=…: Yes for spam and No for other mail, the score, the threshold it was compared with, and the rules that fired. X-Spam-Flag: YES is added only to messages it classed as spam. Administrators can change these fields, so only the default form is interpreted; a Yes or the flag makes the finding a Warning. What the score means: the SpamAssassin score.

rspamd: X-Spamd-Result, X-Rspamd-Action and X-Spam-Status

X-Rspamd-Action holds the action rspamd assigned to the message, such as no action, add header or reject. X-Spamd-Result starts with default:, True or False, and two numbers in brackets: the score and the required score (rspamd's code fills them from task:get_metric_score, which its Lua documentation describes as “2 numbers containing the current score and required score of the metric”); then come the rules that fired, with their points. In rspamd's code (version 4.2.0), True means only that the action was reject, so False does not mean the message is clean. rspamd's own X-Spam-Status says Yes for any action other than no action or greylist. The finding is a Warning for True, for that Yes, and for an X-Rspamd-Action other than no action or greylist.

Spam fields we do not interpret

Other fields with “spam” in their name are listed as written, without a verdict. Some have no public documentation; some are known fields in a form other than the documented one; others are documented but hold no verdict the analyzer reads, such as X-Spam-Level (one * for each full score point in SpamAssassin's and rspamd's defaults), X-Spam-Checker-Version or rspamd's X-Rspamd-Queue-Id. We do not guess what a provider's private field means.

Frequently asked questions

How do I check an email header?

Open the message in your mail app and show its original or source (steps for Gmail, Outlook, Apple Mail and Yahoo), copy it and paste it into the box at the top of this page. Start with the verdict: it is built from your provider's DMARC result, or from its SPF and DKIM results when there is none. Then look at the From and Reply-To addresses and at the server that handed the message over; the phishing checklist goes through them in order.

How do I get the header of an email on my phone?

Google gives the steps for the full header only for Gmail in a browser. In the Gmail app for Android, View details, then View security details, shows who mailed and who signed a message, not the header; for iPhone and iPad Google says: “You can't check authentication on your iPhone or iPad.” If your phone's mail app has no command for the original message, open the same mailbox in a browser on a computer (Gmail, Outlook on the web or Outlook.com, icloud.com/mail or Yahoo Mail) and use the steps above.

Is it safe to paste my headers here?

The header does not leave your device: your browser runs the analysis, and what you paste is not sent to us or anyone else, not put into the page address and not stored (how that works). Only if you open one of the links in the result does that address or domain reach our server, like any check you start on this site; our privacy policy says what we keep.

A header does contain personal data: the names and addresses of the sender and the recipients, and the servers the message passed. Before you post one anywhere else, such as a forum or a support ticket, look at what it contains.

Why can't the analyzer verify DKIM?

Verifying a signature needs two things this page does not use. The public key is published in DNS under the signing domain (RFC 6376: “the SDID value is used to form the query for the public key”), and the analyzer makes no network requests. And bh= is a hash of the body as it was signed (after the canonicalization named in c=), while the analyzer reads only the header. Even with both, the key published today need not be the one that was published when the message arrived. A receiving server that checks DKIM records its verdict as the dkim= result in Authentication-Results, which the analyzer reads.

Can an email header be faked?

Everything the sender writes can: From, Date, Subject, and even Received lines and Authentication-Results added before the message reached your provider. What your provider added on arrival, its own Received lines and its Authentication-Results, is what you can rely on; RFC 8601 requires receiving servers that follow it to delete fields that falsely claim their name. That is why the analyzer looks for the hand-off and takes the verdict only from your provider's results.

Can I trace an email to the sender's IP address from its header?

You can find the address of the server that delivered the message to your provider: it is in your provider's Received line, and the analyzer shows it as the hand-off. That is a mail server, often the sender's mail provider, not necessarily the sender's own device. Lines below it may name earlier servers, but they were written before your provider got the message and cannot be checked.

Is this email header analyzer free?

Yes. There is no sign-up and no limit on how many headers you analyze, because the work happens in your browser. One header can be up to 1,048,576 characters long.

Page updated .