MTA-STS and TLS-RPT: enforcing TLS for inbound mail
How to require TLS for messages sent to your domain, and how to get reports when receivers can't honor your policy.
SMTP defaults to opportunistic encryption — try TLS, fall back to plaintext if it doesn't work. That fallback is exactly what STARTTLS-stripping attackers exploit. MTA-STS lets you tell the world: never deliver to me without TLS, and verify the certificate. TLS-RPT gives you reports when something goes wrong.
Why opportunistic TLS is not enough
By default, an SMTP server sends a STARTTLS upgrade. If the receiver advertises support, the connection is encrypted. If it doesn't — or an on-path attacker strips the upgrade — the message goes out in cleartext. The sender has no way to know it happened. MTA-STS closes this gap by publishing a verifiable policy that says: don't downgrade.
The two pieces
| Standard | Purpose | Direction |
|---|---|---|
| MTA-STS | Enforce TLS to your MX hosts | Inbound (mail TO you) |
| TLS-RPT | Get reports of TLS failures | Inbound reporting |
| DANE/TLSA | Alternative to MTA-STS using DNSSEC | Inbound |
Step 1 — Publish the policy file
Host a plain-text policy at https://mta-sts.<your-domain>/.well-known/mta-sts.txt. Must be served over HTTPS with a valid certificate.
version: STSv1
mode: testing
mx: mail.example.com
mx: mail-backup.example.com
max_age: 604800- `mode: testing` — receivers report failures but still deliver. Always start here.
- `mode: enforce` — receivers refuse to deliver if TLS fails. Move here after testing.
- `mode: none` — turn off MTA-STS gracefully without removing the record.
- `mx:` — list every MX host that should accept mail. Wildcards (
*.example.com) allowed. - `max_age` — how long receivers can cache (in seconds). 1 week (604800) is typical.
Step 2 — Publish the DNS pointer
Two TXT records: one announces the policy and its version (the id should change every time you update the policy file), one for TLS-RPT.
| Host | Type | Value | TTL |
|---|---|---|---|
| _mta-sts.example.com | TXT | v=STSv1; id=20260419120000 | 3600 |
| _smtp._tls.example.com | TXT | v=TLSRPTv1; rua=mailto:[email protected] | 3600 |
Step 3 — Wait and read TLS-RPT
TLS-RPT reports arrive daily as JSON-formatted email attachments. They list every TLS connection attempt to your MX hosts and the outcome. Look for failures: cert mismatches, expired certs, STARTTLS not offered, downgrade attempts.
| Failure | Likely cause | Fix |
|---|---|---|
certificate-expired | MX cert past expiry | Renew immediately |
certificate-host-mismatch | Cert SAN doesn't include the MX hostname | Reissue with correct SAN |
starttls-not-supported | MX doesn't advertise STARTTLS | Configure TLS on the MX |
validation-failure | Cert chain incomplete or untrusted CA | Install full chain |
Step 4 — Move to enforce
- Run in
testingmode for at least 4 weeks. - Confirm TLS-RPT reports show no failures from major receivers (Google, Microsoft, Yahoo).
- Update
mta-sts.txttomode: enforceand bump theidin DNS. - Watch reports for the next 2 weeks. Any new failure now means delivery is blocked.
MTA-STS vs DANE
DANE/TLSA is the DNSSEC-based alternative. It's stronger (signed in DNS, not bootstrapped over HTTPS) but requires DNSSEC, which adds operational complexity. Most teams pick MTA-STS because it works without DNSSEC. Some run both for receivers that prefer one or the other.
Frequently asked questions
Keep reading