MTA-STS
MTA-STS (Mail Transfer Agent Strict Transport Security) is the HSTS of email. It tells sending mail servers: use TLS when you deliver to my domain, and if TLS is not available, do not deliver. Without it, SMTP falls back to plaintext on any connection that can be downgraded, which is every connection on the public internet. Specified in RFC 8461.
How it works
SMTP's built-in encryption (STARTTLS) is opportunistic. The sender asks "can we switch to TLS?" If the receiver says no, or an attacker strips the response, the sender falls back to plaintext and delivers the message anyway. Nobody notices.
MTA-STS fixes this. The sender fetches a policy from DNS and HTTPS before delivery, then enforces TLS against it.
- 01·sending MTAstepTXT? _mta-sts.yourdomain.comresult
v=STSv1; id=20260416T120000Z
- 02·sending MTAstepGET https://mta-sts.yourdomain.com/.well-known/mta-sts.txtresult
version: STSv1 mode: enforce mx: mail.yourdomain.com max_age: 604800
- 03·sending MTAstepconnect to mail.yourdomain.com:25, STARTTLSresult
policy matches, MX is on the list, cert is valid
- 04·sending MTAstepdeliver messageresult
success. enforce mode would have aborted if TLS failed
Both the DNS record and the HTTPS file are required. A valid TXT record with no fetchable policy means the sender ignores MTA-STS (RFC 8461 §3.2).
The three modes
Same policy file, different enforcement level, set by the mode: line inside the policy.
senders fall back to plaintext silently. Equivalent to no MTA-STS at all.
Sudory: faildelivery still proceeds over plaintext when TLS fails, but a TLS-RPT report is filed so you see it.
Sudory: warnTLS failure aborts delivery. Sender retries; TLS-RPT records the block.
Sudory: passStarting at enforce is a mistake. Any MX typo or cert misconfiguration blocks real mail instantly. Start in testing, read the reports, move to enforce once it is quiet.
The two records
Both are required. MTA-STS is invalid with just one.
DNS TXT record at _mta-sts.yourdomain.com:
v=STSv1; id=20260416T120000Zv=STSv1identifies the record.id=is a version string, up to 32 alphanumeric characters. Change it every time the policy file changes so senders fetch the new version. A compact timestamp like20260416T120000Zis common and readable (the RFC uses this shape in its example).
HTTPS policy file at https://mta-sts.yourdomain.com/.well-known/mta-sts.txt, with a valid certificate and Content-Type: text/plain:
version: STSv1
mode: enforce
mx: mail.yourdomain.com
mx: *.mail.yourdomain.com
max_age: 604800mx:lists every MX host the policy allows. Wildcards match one label:*.mail.example.commatchesa.mail.example.combut notexample.comora.b.mail.example.com.max_age:is the cache lifetime in seconds. A week (604800) is typical. Spec maximum is 31,557,600 (about a year).
TLS-RPT (reporting)
MTA-STS tells senders what to do. TLS-RPT (RFC 8460) tells them where to send failure reports. Publish it as a separate TXT record at _smtp._tls.yourdomain.com:
v=TLSRPTv1; rua=mailto:tls-reports@yourdomain.comWithout TLS-RPT, testing mode is silent: the sender logs failures in its own pipeline, not yours. With it, you get daily aggregate reports (same shape as DMARC's) listing every sender that attempted delivery and whether TLS succeeded.
The rollout
- Publish TLS-RPT first. Collect baseline reports for a few weeks. You see what portion of your inbound mail is already TLS-encrypted, and from where.
- Publish the policy in
testingmode. No delivery impact. Reports now include MTA-STS policy-match results. - Fix the gaps. MX hosts missing from the policy, expired certs on the MX, misconfigured subdomains. Whatever the reports flag.
- Switch to
enforce. Bumpid=so senders re-fetch. From here on, any sender that honours MTA-STS and cannot negotiate TLS bounces the message.
The two largest mailbox providers already enforce MTA-STS on outbound delivery. Google Workspace checks the recipient's MTA-STS policy before delivering Gmail traffic. Microsoft 365 / Exchange Online does the same, on by default. Smaller systems may not. MTA-STS is additive: it hardens what can be hardened, leaves the rest alone.
Common mistakes
- Policy file without DNS record (or vice versa). Both are required. The DNS record tells senders a policy exists; the file is the policy. Miss either and MTA-STS falls back to opportunistic TLS.
- Cert on
mta-sts.yourdomain.comexpired or self-signed. Senders refuse to fetch a policy over a bad HTTPS connection. Use a valid public cert (Let's Encrypt works). - MX list in the policy out of sync with DNS. Add a new MX in DNS but forget the policy, and enforce mode blocks mail to the new host.
- Forgetting to bump
id=. Senders cache the policy for up tomax_ageseconds. Change the file without theid=, and nobody picks it up for a week. - Starting in
enforce. Skiptestingand the first cert or MX mistake blocks real mail with no warning. Always stage.
Check your MTA-STS setup: scan your domain. Sudory reads the DNS record, fetches the HTTPS policy, verifies the certificate, and reports your mode.
