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.

Inbound delivery with MTA-STSsender side
  1. 01·sending MTA
    stepTXT? _mta-sts.yourdomain.com
    result
    v=STSv1; id=20260416T120000Z
  2. 02·sending MTA
    stepGET https://mta-sts.yourdomain.com/.well-known/mta-sts.txt
    result
    version: STSv1
    mode: enforce
    mx: mail.yourdomain.com
    max_age: 604800
  3. 03·sending MTA
    stepconnect to mail.yourdomain.com:25, STARTTLS
    result
    policy matches, MX is on the list, cert is valid
  4. 04·sending MTA
    stepdeliver message
    result
    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.

mode: noneadvisory

senders fall back to plaintext silently. Equivalent to no MTA-STS at all.

Sudory: fail
mode: testingobserve

delivery still proceeds over plaintext when TLS fails, but a TLS-RPT report is filed so you see it.

Sudory: warn
mode: enforcehard fail

TLS failure aborts delivery. Sender retries; TLS-RPT records the block.

Sudory: 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 invalid with just one.

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

v=STSv1; id=20260416T120000Z
  • v=STSv1 identifies 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 like 20260416T120000Z is 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: 604800
  • mx: lists every MX host the policy allows. Wildcards match 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. 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.com

Without 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

  1. 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.
  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, expired certs on the MX, misconfigured subdomains. Whatever the reports flag.
  4. Switch to enforce. Bump id= 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.com expired 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 to max_age seconds. Change the file without the id=, and nobody picks it up for a week.
  • Starting in enforce. Skip testing and 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.

Aleksej Dix
Aleksej DixFounder of Sudory

Founder of Sudory. Frontend engineer based in Zurich with 20+ years shipping production web apps; now building continuous compliance scanning and writing about the DNS and email-auth controls behind it. Co-founder of WebZurich.