MTA-STS Explained: What It Is, TLS-RPT and Do You Need It
MTA-STS makes senders require TLS with a valid certificate when delivering mail to your domain. Record, policy file, TLS-RPT reports and a safe rollout order.
Published: · 7 min read
MTA-STS (RFC 8461) lets a domain tell sending mail servers: "deliver mail for me only over TLS, only with a valid certificate, and only to these MX hosts". Without it, encryption between mail servers is opportunistic and can be removed by anyone sitting on the path. It consists of one TXT record, one small text file served over HTTPS, and ideally a second TXT record (TLS-RPT, RFC 8460) that gets you daily reports about what senders experienced. If your mail is hosted with a large provider, the cost is an afternoon; if you receive anything sensitive by email, it is worth it.
The problem: STARTTLS is opportunistic
SMTP between servers starts in plain text. The receiving server advertises STARTTLS, the sender upgrades the connection, and the rest is encrypted. Two weaknesses are built in:
- Downgrade. An attacker on the path can delete the
STARTTLSline from the server's reply. The sender concludes that TLS is not offered and delivers in clear text. - No authentication. Senders typically do not validate the certificate they are shown, because for decades many mail servers had self-signed or mismatched ones. An attacker who can spoof the answer to your MX query, or intercept the connection, can present any certificate.
The three parts
1. The _mta-sts TXT record
$ dig +short TXT _mta-sts.example.com
"v=STSv1; id=20260921000000"
id is any string of up to 32 letters and digits. Its only job is to change whenever the policy changes, so that senders know to fetch the file again.
2. The policy file
Served at a fixed URL on the fixed hostname mta-sts:
$ curl https://mta-sts.example.com/.well-known/mta-sts.txt
version: STSv1
mode: testing
mx: mx1.mail.example.net
mx: mx2.mail.example.net
max_age: 86400
| Field | Meaning |
|---|---|
version |
Always STSv1 |
mode |
enforce, testing or none |
mx |
One line per allowed MX host. A wildcard such as *.mail.example.net is allowed and matches exactly one leftmost label |
max_age |
How long senders may cache the policy, in seconds. Maximum 31557600 (about one year) |
The HTTPS server must present a publicly trusted certificate that is valid for mta-sts.example.com. Senders do not follow HTTP redirects when fetching the policy, so the file has to be served at that exact URL.
3. MX hosts that pass
Every host listed must offer STARTTLS with a certificate that is unexpired, chains to a certificate authority the sender trusts, and matches the MX hostname.
$ openssl s_client -starttls smtp -connect mail.example.com:25 \
-servername mail.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -enddate -ext subjectAltName
If the certificate on your own MX has run out, fix that first: SSL certificate expired: what to do covers the renewal side.
How a sender uses the policy
- Before delivering to
example.com, the sender looks up_mta-sts.example.com. - If it has no cached policy, or the
iddiffers from the cached one, it fetches the policy file over HTTPS. - It caches the policy for
max_ageseconds. - It resolves the MX records as usual, then discards any MX host that does not match an
mx:line, and requires valid TLS on the rest.
What happens on failure depends on the mode:
| Mode | On a TLS or MX mismatch failure |
|---|---|
testing |
The message is delivered anyway; the failure is reported via TLS-RPT |
enforce |
The sender does not deliver to the failing host. If no host passes, the message is queued and retried, and eventually bounces |
none |
The domain declares it has no active policy. Used to withdraw |
The cache is what gives MTA-STS its strength. An attacker who blocks the TXT lookup or the HTTPS fetch today cannot make a sender forget a policy it cached last week. The weak moment is the very first fetch, before anything is cached.
TLS-RPT: find out what senders see
$ dig +short TXT _smtp._tls.example.com
"v=TLSRPTv1; rua=mailto:tlsrpt@example.com"
rua takes a mailto: address or an https: URI. Participating senders send an aggregate JSON report per day: how many sessions to your domain succeeded, how many failed, and why (expired certificate, hostname mismatch, STARTTLS not offered, MX not in policy). Reports cover both MTA-STS and DANE. Without them, testing mode tests nothing, because nobody tells you the result.
Rollout order
- Confirm that every MX host has a valid, matching, publicly trusted certificate (command above).
- Publish the TLS-RPT record first and let reports start arriving.
- Host the policy file with
mode: testingand a shortmax_agesuch as86400. - Publish the
_mta-stsTXT record. - Read reports for a few weeks. Look for failures from legitimate senders and for MX hosts missing from the policy.
- Switch to
mode: enforce, change theid, and keepmax_ageshort for the first days. - Raise
max_ageto a matter of weeks once things are quiet. - Put the
mta-stscertificate and the MX certificates under expiry monitoring.
To look at the published _mta-sts record and policy of a domain, use the MTA-STS checker; for the reporting record, the TLS-RPT checker.
Hosted mail
If your MX records point at a mail provider, the certificates are the provider's job and large providers have them in order. Your part:
- List the provider's MX names in the policy exactly as they appear in your MX records, or with the wildcard form the provider documents.
- Host the policy file yourself on
mta-sts.example.com. A static page host is enough.
Changing mail provider
Order matters once you are in enforce. Senders hold a cached policy that lists only the old MX hosts. If you switch the MX records first, those senders see new hosts that the policy does not allow and refuse to deliver.
- Add the new provider's MX names to the policy file (keep the old ones) and change the
id. - Give senders time to notice the new
idand refetch the policy; a few days is a careful margin. - Switch the MX records.
- Later, remove the old names from the policy and change the
idagain.
This is also the reason not to jump to a one-year max_age early.
Withdrawing a policy
Deleting the TXT record and the file is not a withdrawal. Senders with a cached enforce policy keep enforcing it until their cache expires. The clean way: publish mode: none with a new id, keep both the record and the file in place until the previous max_age has fully elapsed, then remove them.
MTA-STS and DANE
DANE for SMTP (RFC 7672) solves the same problem differently: the MX host's certificate or key is pinned in a TLSA record, and that record is trusted because the zone is signed with DNSSEC.
| MTA-STS | DANE for SMTP | |
|---|---|---|
| Trust anchor | Web PKI (public CAs) plus HTTPS | DNSSEC chain |
| Needs DNSSEC | No | Yes: the TLSA records of the MX hosts must be in a signed zone |
| First-contact weakness | Yes, until the policy is cached | No |
They can coexist, and TLS-RPT reports on both. With hosted mail, DANE depends on whether your provider signs its MX zone; MTA-STS is in your own hands. See DNSSEC explained.
What MTA-STS does not do
- It protects inbound mail to your domain only. Your outbound mail is protected by the recipients' policies, if your sending server honours MTA-STS.
- It only works with senders that implement it. Others continue to deliver opportunistically.
- It is hop-to-hop transport encryption, not end-to-end. The mail is readable on every server it passes through.
- It says nothing about spam, spoofing or sender authentication. That is the job of SPF, DKIM and DMARC: see MX, SPF, DKIM and DMARC explained.
Do you need it?
- Domain on large hosted mail: low cost, low risk. The provider's certificates are maintained; you add two TXT records and a static file.
- Domain that receives sensitive mail (contracts, health, finance, account resets): worthwhile even if you run your own MX, provided you monitor certificates.
- Not ready to commit:
testingmode plus TLS-RPT carries no delivery risk and tells you whetherenforcewould hurt.
Common mistakes
- Going straight to
enforcewithout TLS-RPT, and learning about failures from people whose mail bounced. - Editing the policy file and leaving the
idunchanged. Senders keep the old policy untilmax_ageruns out. - Listing the domain (
example.com) on themx:line instead of the MX hostnames. - A policy file that is reachable only through a redirect, or under a certificate that does not cover
mta-sts.example.com. - Letting the certificate of the
mta-stshost expire: new senders can no longer fetch the policy. - Switching MX records before updating the policy, or deleting everything at once to "turn it off".
Check it with OrbitProbe
Start with the OrbitProbe MX lookup: it lists a domain's MX hosts with their preferences, together with the SPF and DMARC records. The host names it shows are the ones your mx: lines must match, character for character, so run it before writing the policy and again after any change of mail provider. A DNS lookup shows what is published now; whether senders could actually negotiate TLS is what the TLS-RPT reports are for, so keep reading those after you move to enforce.