MTA-STS

MTA-STS (Mail Transfer Agent Strict Transport Security) is the HSTS of email. It tells sending mail servers: "when you deliver mail to my domain, use TLS, 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. The protocol is specified in RFC 8461.

How it works

SMTP's built-in encryption (STARTTLS) is opportunistic. A sending server asks the receiver "can we switch to TLS?" If the receiver says no, or an on-path attacker strips the response, the server falls back to plaintext and sends the mail anyway. Nobody notices.

MTA-STS fixes this with a policy that the sender fetches before delivery:

  1. A DNS TXT record at _mta-sts.yourdomain.com announces "I have a policy; here's its version."
  2. An HTTPS-served policy file at https://mta-sts.yourdomain.com/.well-known/mta-sts.txt lists your allowed MX hosts and the enforcement mode.
  3. Sending servers cache the policy and, on every subsequent delivery, require TLS and verify the receiving MX matches the list. If the receiving MX presents an invalid cert or does not support TLS, delivery is aborted.

The DNS record is cheap. The HTTPS file is the policy. Both are required: if a valid TXT record exists but no policy can be fetched over HTTPS, senders proceed as if MTA-STS were not deployed (RFC 8461 §3.2).

The three modes

Same policy file, different enforcement level. Set with the mode: line inside the policy:

ModeBehaviour on TLS failureSudory verdict
nonePolicy is advisory. Senders fall back to plaintext silently. Equivalent to no MTA-STS at all.Fail
testingDelivery proceeds over plaintext, but the sender files a TLS-RPT report so you see the failure.Warn
enforceDelivery is aborted. The sender queues and retries, and the TLS-RPT report records the block.Pass

Starting 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 not valid with just one.

DNS TXT record at _mta-sts.yourdomain.com:

v=STSv1; id=20260416T120000Z
  • v=STSv1 identifies the record.
  • id= is an opaque version string, up to 32 alphanumeric characters. Change it whenever the policy file changes so senders fetch the new version. A compact timestamp like 20260416T120000Z is a common and readable choice (the RFC's own example uses this shape).

HTTPS policy file served at https://mta-sts.yourdomain.com/.well-known/mta-sts.txt, with a valid certificate and the text/plain content type:

version: STSv1
mode: enforce
mx: mail.yourdomain.com
mx: *.mail.yourdomain.com
max_age: 604800
  • mx: must list every MX host the policy allows. Wildcards match exactly one label; *.mail.example.com matches a.mail.example.com but not example.com or a.b.mail.example.com.
  • max_age: is the cache lifetime in seconds. A week (604800) is typical. The maximum permitted by the spec is 31,557,600 seconds (roughly one year).

TLS-RPT (reporting)

MTA-STS tells senders what to do. TLS-RPT (defined in RFC 8460) tells them where to send failure reports. Publish it separately, as a TXT record at _smtp._tls.yourdomain.com:

v=TLSRPTv1; rua=mailto:tls-reports@yourdomain.com

Without TLS-RPT, testing mode is silent: the sender logs the failure to its own ops pipeline, not yours. With it, you get daily aggregate reports similar in shape to DMARC aggregate reports, listing every sender who attempted delivery and whether TLS succeeded.

The rollout

  1. Publish TLS-RPT first. Collect baseline reports for a couple of weeks. You will see how much of your inbound mail is already TLS-encrypted and from where.
  2. Publish the policy in testing mode. No delivery impact. Reports now include MTA-STS policy-match results.
  3. Fix the gaps. MX hosts missing from the policy, cert expiry on the MX, misconfigured subdomains. Anything the reports flag.
  4. Switch to enforce. Bump the id= so senders re-fetch. From this point, mail from any sender who honours MTA-STS and cannot negotiate TLS is bounced.

The two largest mailbox providers enforce MTA-STS on outbound delivery today. Google Workspace validates the MTA-STS policy of every recipient domain before delivering Gmail traffic. Microsoft 365 / Exchange Online does the same, on by default. Smaller or older systems may not, which is why MTA-STS is additive: it hardens what can be hardened and leaves the rest untouched.

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. Missing either one makes MTA-STS invalid and senders revert to opportunistic TLS.
  • Cert on mta-sts.yourdomain.com expired or self-signed. Senders refuse to fetch a policy over a bad HTTPS connection. A valid public cert (Let's Encrypt works) is the requirement.
  • MX list in the policy out of sync with DNS. If you add a new MX in DNS but forget to add it to the policy file, enforcing mode blocks mail to the new MX.
  • Forgetting to bump id=. Senders cache the policy for up to max_age seconds. If you change the policy file but not the DNS id=, nobody notices for a week.
  • Starting in enforce. Skipping testing means the first cert or MX mistake blocks real mail with no warning. Always pass through testing and read the TLS-RPT reports.

Check whether your domain has a valid MTA-STS policy: scan your domain. Sudory reads the DNS record, fetches the HTTPS policy file, verifies the certificate, and tells you which mode you're on.