← Back to blogGuides

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 STARTTLS line 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

  1. Before delivering to example.com, the sender looks up _mta-sts.example.com.
  2. If it has no cached policy, or the id differs from the cached one, it fetches the policy file over HTTPS.
  3. It caches the policy for max_age seconds.
  4. 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: testing and a short max_age such as 86400.
  • Publish the _mta-sts TXT 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 the id, and keep max_age short for the first days.
  • Raise max_age to a matter of weeks once things are quiet.
  • Put the mta-sts certificate 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.

  1. Add the new provider's MX names to the policy file (keep the old ones) and change the id.
  2. Give senders time to notice the new id and refetch the policy; a few days is a careful margin.
  3. Switch the MX records.
  4. Later, remove the old names from the policy and change the id again.

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: testing mode plus TLS-RPT carries no delivery risk and tells you whether enforce would hurt.

Common mistakes

  • Going straight to enforce without TLS-RPT, and learning about failures from people whose mail bounced.
  • Editing the policy file and leaving the id unchanged. Senders keep the old policy until max_age runs out.
  • Listing the domain (example.com) on the mx: 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-sts host 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.