What the mail check
reads, and what it cannot see.
The mail check reads what a domain publishes about its mail: who may send as it, what a receiver should do with a message that fails, where its mail is delivered and how that delivery is protected. This page says what it reads, how to read the report, and the limits that apply to every check it runs.
What is read
DNS records the domain published for strangers to
read. The sender policy (SPF) and every name it includes, the
DMARC record at _dmarc, the mail exchangers (MX), the
MTA-STS and TLS reporting records at _mta-sts and
_smtp._tls, the DANE records of each exchanger, and signing
keys (DKIM) under the selectors the report names. The questions go to
the resolver the scanning machine already uses, so the domain being
checked is not contacted for any of this.
Two connections, and only where they are allowed.
Where a zone announces an MTA-STS policy, the policy file is fetched
from the one address RFC 8461 fixes for it. And each exchanger, at most
eight, is asked on port 25 whether it accepts an encrypted connection:
a greeting, EHLO, STARTTLS, the handshake and
QUIT. No sender, recipient or message is named, so nothing
is delivered and nothing is asked about a person.
This deployment makes neither connection: both are made
only by an installation that has been shown control of the domain, and
by the command line.
The one question that names a recipient
An exchanger inside the domain being checked — say
mail.example.com under example.com — is also
asked whether it forwards mail for a domain it does not serve. That is an
open relay: a server anybody can send through, in anybody's name. It is
the oldest misconfiguration in mail and still the most expensive one to
have, because a relay is found within hours and listed everywhere soon
after, and then the domain's own mail stops arriving.
It cannot be answered from DNS: a configuration can look right and a
server can still accept. So the question is put, in three lines that
cannot deliver anything — an empty sender, which is what every bounce
carries and names nobody; a recipient under .invalid, which
RFC 2606 reserves so that the name cannot exist; and then a reset, before
any message. DATA is never sent, so a server that agreed was
never handed anything to forward, and what is graded is what it said it
would do.
An exchanger run by somebody else is never asked. A provider named by an MX record is not the operator's server: there the conversation reads as a spam probe, and the address it came from is what gets listed for it. There is no setting that widens this.
How to read a report
Findings are graded, and only where a standard calls
something an error: more than one SPF record, more than ten lookups to
evaluate one, +all, two DMARC records, a policy file no
sending server would apply. Each finding names its rule and cites the
document.
Observed is what the check established and deliberately
does not grade. ~all is the staging position,
p=none is the monitoring position, and a domain may
reasonably choose MTA-STS, DANE, both or neither. A report that marked
those down would be calling a correct decision a fault. The number of
lookups a sender policy costs is reported before it is a fault, because
a domain at nine of ten is one provider change away from losing its
policy.
Not established for this host is what this particular check could not settle: a record the resolver would not answer, an exchanger that would not talk, a selector list that found no key. Nothing read is never reported as nothing published, because the two send an operator to opposite places.
Limits of this method are below. They are true of every mail check, so they are stated once, here.
When an exchanger does not answer
An exchanger may refuse the greeting of the machine asking, before encryption comes up. The most common reason is the address that machine connects from: many mail services turn away an address with no reverse DNS name, and a home or VPN connection usually has none. The report says the exchanger's offer was not established, never that it was refused, because the refusal was of the scanner and not of encryption.
Running your own copy, give the server's address a reverse DNS name
that resolves back to it, and pass that name with -helo.
A network that blocks outbound port 25, as many cloud providers do by
default, is reported as that and not as a fault of the exchanger.
No message was sent
No message was composed or sent, and nothing that would change state at the other end was attempted: there is no DATA in any of this, so nothing can be delivered or queued. Where a mail exchanger inside the domain was contacted, it was also asked whether it forwards mail for a domain it does not serve — an empty sender, a recipient at a name RFC 2606 reserves so that it cannot exist, and a reset before any message. An exchanger run by somebody else is never asked that. Where DANE is published, a binding is checked only against a certificate an exchanger presented to this scan, and DNSSEC is not validated here: whether the records validated is the resolver's word. And a DKIM signing key is read only under a selector this scan was told to look under: DNS cannot list what is beneath a name, so which selectors were tried — if any — is said in the report itself rather than here.
What else is written down
This check has its own rule set, separate from the ones that grade a TLS handshake and a website. What those can and cannot see is on the Transport page and the Reach page.
Every property this project holds itself to is in docs/invariants.md, and the mail check's is N13. What changed between rule sets is in docs/policy-changes.md.
What is recorded about a check here, and how to have a domain excluded, are on the privacy page.