MTA-STS explained: forcing TLS on inbound mail.

STARTTLS encrypts mail between servers, but only if nobody in the path says otherwise. MTA-STS is how a receiving domain tells senders "insist on it, and refuse to deliver if you cannot". Here is what it does, how to publish it, and how to do that without losing mail.

Published 2026-09-16 · 7 min read · Kirk Diamond

The problem with STARTTLS

SMTP between mail servers starts in plain text. The receiving server advertises STARTTLS in its response to EHLO, the sender asks for it, and the connection upgrades to TLS. Almost every mail server does this today, and the email deliverability checker will show you the TLS version each of your MX hosts negotiates.

The weakness is that the whole thing is opportunistic. If the STARTTLS line is missing from the EHLO response, the sender carries on in plain text. Anyone who can sit between the two servers can strip that one line and read everything, and this has been done at ISP scale. Even with STARTTLS, most sending servers do not validate the receiver's certificate: an expired, self-signed or wrong-name certificate is accepted, because refusing would mean not delivering, and mail administrators have always chosen delivery. And the MX lookup itself is unauthenticated unless the zone is DNSSEC-signed, so an attacker who can forge a DNS answer can point the sender at their own server.

What MTA-STS adds

MTA-STS (RFC 8461) lets the receiving domain publish a policy that says: my mail servers are these hostnames, they support TLS, the certificate must be valid for the hostname, and if you cannot get that, do not deliver. A sender that supports MTA-STS fetches the policy over HTTPS, so it cannot be tampered with in transit, caches it for as long as the policy says, and applies it to every delivery attempt. Gmail, Outlook.com and most large providers enforce policies as senders. Smaller mail servers mostly do not yet, which is fine: for them nothing changes.

The two parts

1. The DNS record

A TXT record at _mta-sts.example.com:

_mta-sts.example.com.  TXT  "v=STSv1; id=20260916T120000;"

The id is a version marker. Senders cache your policy and only re-fetch it when the id changes, so every time you edit the policy file you must change the id. A timestamp works well. Forgetting this step is the most common reason a policy change appears to do nothing.

2. The policy file

Served over HTTPS at https://mta-sts.example.com/.well-known/mta-sts.txt, with a certificate valid for mta-sts.example.com, as text/plain:

version: STSv1
mode: testing
mx: mail1.example.com
mx: mail2.example.com
mx: *.mail.example.net
max_age: 86400

Every MX hostname you publish must appear here, exactly or via a single-label wildcard. The certificates on those MX hosts must be valid for those names: publicly trusted, not expired, hostname matching. A sender enforcing the policy will refuse to deliver to a host whose certificate does not check out, so this is the moment to fix the mail server certificate you have been ignoring. max_age is how long senders may cache the policy, in seconds; start short, grow it later.

Testing mode first, always

The mode line has three values. none publishes the policy but asks senders to do nothing with it, useful for switching off. testing asks senders to validate but still deliver on failure, and to tell you about the failures. enforce means refuse to deliver on failure. Start in testing and stay there until the reports (below) have been clean for a few weeks. A typo in an MX hostname in enforce mode stops inbound mail from every large provider at once, and you will not notice until someone phones.

TLS-RPT: finding out whether it works

MTA-STS on its own gives you no feedback. TLS-RPT (RFC 8460) is the companion record that asks senders to report TLS failures to you, daily, as JSON:

_smtp._tls.example.com.  TXT  "v=TLSRPTv1; rua=mailto:[email protected]"

Reports say which sender, which MX, how many sessions succeeded and which failure type was seen (certificate expired, hostname mismatch, STARTTLS not offered, policy could not be fetched). In testing mode these are what tell you whether you are ready to enforce. In enforce mode they are your alarm. Point rua at a mailbox or a service that parses them; the JSON is readable by hand but tedious after the first week.

A rollout that will not lose mail

  1. Fix the MX certificates. Run the SSL/TLS checker on port 25 against each MX host and get every one to a trusted, matching certificate.
  2. Publish TLS-RPT and confirm a report arrives within a day or two.
  3. Publish the policy file in testing mode with a max_age of a day, then the DNS record.
  4. Check it with the email deliverability checker, which fetches and validates the policy file and flags an MX that is not covered.
  5. Read the TLS-RPT reports for at least two weeks. Every failure is something that will become a bounce in enforce mode.
  6. Switch to enforce, change the id, and raise max_age to a week or two once you are confident. Longer cache means better protection but slower recovery if you need to change the policy.

Things that catch people

All guides · All tools