The problem MTA-STS solves
SMTP between servers is opportunistically encrypted. The sending MTA connects on port 25, the receiver advertises STARTTLS, and the sender upgrades the connection. Nothing in that exchange is authenticated: an attacker positioned between the two hosts can strip the STARTTLS advertisement from the receiver's greeting, and a well-behaved sender will silently fall back to plaintext. Most senders will also accept an expired, self-signed, or wrong-hostname certificate, because refusing would mean bouncing legitimate mail.
MTA-STS (RFC 8461) fixes this by letting a domain publish a policy, out of band over HTTPS, that says: *my MX hosts are these, they support TLS, and their certificates validate — if you cannot get that, do not deliver.* Because the policy is fetched over HTTPS with normal certificate validation and then cached for max_age, an attacker who can tamper with SMTP cannot forge or suppress it.
The two halves that must both exist
MTA-STS is deliberately split across DNS and HTTPS, and a domain with only one half is in a worse position than a domain with neither, because it looks configured while doing nothing.
Read the full explanation of mta-sts & tls-rpt checker results ↓Show less ↑
1. The DNS TXT record
_mta-sts.example.com. 3600 IN TXT "v=STSv1; id=20260901T120000;"The id is an opaque version string of up to 32 alphanumeric characters. Senders cache your policy and re-fetch it only when the id changes — so you must bump the id every time you edit the policy file, or senders will keep using the cached copy until max_age expires. A date-stamp format like 20260901T120000 is the convention.
2. The HTTPS policy file
Served as text/plain at https://mta-sts.<domain>/.well-known/mta-sts.txt, from a host whose certificate is valid for mta-sts.<domain>:
version: STSv1
mode: enforce
mx: mx1.example.com
mx: mx2.example.com
mx: *.mail.example.com
max_age: 604800mta-sts.example.com to www.example.com silently breaks the whole mechanism. This checker reports a redirect as a failure rather than following it.Reading each policy field
| Field | Values | Notes |
|---|---|---|
| version | STSv1 | Must be exactly this. Anything else means the whole policy is ignored. |
| mode | enforce, testing, none | Only enforce actually prevents downgrade. testing reports failures but still delivers. none is how you retire a policy safely. |
| mx | hostname or *.hostname | One line per pattern. A single leading *. wildcard matches exactly one label — *.example.com matches a.example.com but not a.b.example.com. |
| max_age | 1 – 31557600 seconds | How long senders cache the policy. 604800 (one week) is the usual production value. |
The mx list must cover every host in your MX record set. This checker resolves your real MX records and reports any that the policy does not match, because that is the failure that takes mail down: in enforce mode, a sender that resolves an uncovered MX host refuses to deliver to it entirely. Cross-check your MX set with the MX lookup tool whenever you change mail providers.
A short max_age weakens the protection: it is the window an attacker gets after a policy is withdrawn, and also the window in which senders re-check. Anything under a day gives an attacker a realistic opportunity. The exception is during rollout, where a short value lets you back out quickly — set 86400 while testing, raise it to 604800 once you are confident.
TLS-RPT: the part people skip
TLS-RPT (RFC 8460) is a separate TXT record that asks senders to send you daily JSON reports about TLS negotiation outcomes:
_smtp._tls.example.com. 3600 IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"Publish this before you set mode: enforce, not after. It is the only way to discover that some sender cannot validate your certificate, or that one of your MX hosts is missing from the policy, without users reporting bounced mail. The reports name the sending organisation, the policy they applied, and the count of successful and failed sessions. rua accepts mailto: and https: destinations, comma-separated.
_smtp._tls record tells you how often senders are already failing to negotiate TLS with your MX hosts — often a surprise.A safe rollout order
- Confirm every MX host answers on port 25 with STARTTLS and a certificate valid for its own hostname. Check the certificate with the SSL certificate checker and reachability with the SMTP connection test.
- Publish the TLS-RPT record at
_smtp._tls.<domain>and wait a week for reports. - Stand up
mta-sts.<domain>with a valid certificate, serving the policy file withmode: testingandmax_age: 86400. - Publish the
_mta-sts.<domain>TXT record with an id. - Watch TLS-RPT reports for a fortnight. Any failures now are exactly the failures that would have bounced mail in enforce mode.
- Change the policy file to
mode: enforce, raisemax_ageto 604800, and bump the id in the TXT record. Both edits, every time.
To retire a policy, never simply delete it — senders holding a cached enforce policy will keep enforcing it for up to max_age. Instead set mode: none, bump the id, wait out the old max_age, and only then remove the DNS record and the host.
Checking MTA-STS from the command line
# 1. The DNS half
dig +short _mta-sts.example.com TXT
dig +short _smtp._tls.example.com TXT
# 2. The HTTPS half — note --max-redirs 0, a redirect here is a bug
curl -sS --max-redirs 0 -i https://mta-sts.example.com/.well-known/mta-sts.txt
# 3. Do the MX hosts in the policy match reality?
dig +short example.com MX | sort -n
# 4. Does each MX host actually present a valid certificate on port 25?
openssl s_client -starttls smtp -connect mx1.example.com:25 \
-servername mx1.example.com -verify_return_error < /dev/null 2>&1 \
| grep -E 'Verify return code|subject=|DNS:'Step 4 is the one that catches real outages. -verify_return_error makes openssl fail rather than warn, which is what an MTA-STS-enforcing sender effectively does. If it prints anything other than Verify return code: 0 (ok), that host will refuse mail from enforcing senders once your policy goes live.
MTA-STS and DANE solve the same problem differently: DANE anchors the certificate in DNSSEC-signed TLSA records, MTA-STS anchors it in the web PKI plus HTTPS. They coexist happily, and large receivers support both. If your zone is already DNSSEC-signed — check with the DNSSEC checker — DANE is worth adding alongside.