MTA-STS: How to Set Up Strict Transport Security for Email
What Is MTA-STS?
MTA-STS (Mail Transfer Agent Strict Transport Security) is defined in RFC 8461. It allows a domain to declare that it supports TLS for incoming email and that sending servers should refuse to deliver mail over an unencrypted connection.
Without MTA-STS, SMTP connections are opportunistic — a man-in-the-middle attacker can strip the STARTTLS offer from the server's response, forcing the connection to fall back to plaintext. This is called a TLS downgrade attack.
MTA-STS solves this by publishing a policy that tells senders: "My mail servers support TLS. If you can't establish a secure connection, don't deliver the message."
Why MTA-STS Matters
SMTP was designed without encryption. STARTTLS was added later as an opportunistic upgrade, but it has a fundamental weakness: the initial negotiation happens in plaintext, making it vulnerable to interception.
MTA-STS addresses this by providing an out-of-band mechanism (HTTPS) for senders to discover your TLS policy. Key benefits:
- Prevents TLS stripping: Attackers cannot downgrade connections to plaintext.
- Certificate validation: Senders verify your mail server's TLS certificate matches the policy, preventing MITM with rogue certificates.
- No DNSSEC required: Unlike DANE, MTA-STS relies on HTTPS (WebPKI) rather than DNSSEC, making it easier to deploy.
- Complements DANE: If you have DNSSEC, deploy both. MTA-STS covers senders that don't validate DANE.
3-Step Setup
Step 1: Publish the DNS TXT Record
Add a TXT record at _mta-sts.example.com (replace example.com with your domain):
_mta-sts.example.com. IN TXT "v=STSv1; id=20260509001"
The id field is a version identifier. Senders cache your policy and re-fetch it when the id changes. Use a timestamp or incrementing number — change it whenever you update the policy file.
Step 2: Host the Policy File
Create a text file and serve it at exactly this URL:
https://mta-sts.example.com/.well-known/mta-sts.txt
The file content:
version: STSv1 mode: enforce mx: mail.example.com mx: *.example.com max_age: 604800
Policy Fields
| Field | Required | Description |
|---|---|---|
version | Yes | Must be STSv1 |
mode | Yes | enforce, testing, or none |
mx | Yes | One or more MX hostnames (wildcards allowed with *. prefix) |
max_age | Yes | Policy lifetime in seconds (recommended: 604800 = 1 week minimum) |
Mode values:
testing— Senders report failures (via TLS-RPT) but still deliver. Use this first.enforce— Senders refuse delivery if TLS fails. Switch to this after confirming no issues.none— Disables the policy. Use only to explicitly revoke a previous policy.
Step 3: Configure the Web Server
The policy must be served over HTTPS on the mta-sts subdomain with a valid certificate. The certificate must be issued by a publicly trusted CA (not self-signed).
Nginx example:
server {
listen 443 ssl;
server_name mta-sts.example.com;
ssl_certificate /etc/letsencrypt/live/mta-sts.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mta-sts.example.com/privkey.pem;
location = /.well-known/mta-sts.txt {
root /var/www/mta-sts;
default_type text/plain;
}
}
Apache example:
<VirtualHost *:443>
ServerName mta-sts.example.com
DocumentRoot /var/www/mta-sts
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mta-sts.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mta-sts.example.com/privkey.pem
<Location /.well-known/mta-sts.txt>
ForceType text/plain
</Location>
</VirtualHost>
Static hosting (GitHub Pages, Cloudflare Pages, etc.): Create a repository with the file at .well-known/mta-sts.txt and point the mta-sts subdomain CNAME to your hosting provider.
Testing Your Configuration
After deploying, verify each component:
- DNS record:
dig TXT _mta-sts.example.com— should return yourv=STSv1; id=...record. - Policy file:
curl https://mta-sts.example.com/.well-known/mta-sts.txt— should return your policy. - Certificate:
openssl s_client -connect mta-sts.example.com:443 -servername mta-sts.example.com— verify the certificate is valid and matches. - MX match: Confirm every hostname in your MX records matches at least one
mx:line in the policy.
Use our Domain Security Scanner to automatically check your MTA-STS configuration.
Recommended Rollout
- Deploy with
mode: testingand a shortmax_age(86400 = 1 day). - Set up TLS-RPT to receive failure reports: add a DNS record
_smtp._tls.example.com TXT "v=TLSRPTv1; rua=mailto:tls-reports@example.com" - Monitor reports for 1–2 weeks. Fix any issues.
- Switch to
mode: enforceand increasemax_ageto 604800 (1 week) or higher.
Common Mistakes
1. MX Hostnames Don't Match the Policy
If your MX record points to mail.example.com but your policy only lists mx: example.com, senders will reject delivery in enforce mode. List every MX hostname explicitly, or use a wildcard: mx: *.example.com.
2. Invalid or Expired Certificate
The certificate on mta-sts.example.com must be valid and issued by a trusted CA. Self-signed certificates will cause policy fetch failures. Use Let's Encrypt for free automated certificates.
3. Policy File Not Accessible
The file must be at exactly /.well-known/mta-sts.txt on port 443. Common issues:
- Redirects (301/302) — the file must be served directly, not redirected.
- Wrong content type — should be
text/plain. - Firewall blocking the
mta-stssubdomain.
4. max_age Too Short
A very short max_age (under 86400) weakens protection because senders re-fetch the policy frequently, giving attackers a window to intercept the fetch. Use at least 604800 (1 week) in production.
5. Forgetting to Update the DNS id
When you change the policy file, update the id in the DNS TXT record. Senders only re-fetch the policy when the id changes. If you forget, senders will use the cached (old) policy until max_age expires.
6. Jumping Straight to Enforce
Always start with mode: testing. In enforce mode, any TLS misconfiguration (expired cert, wrong hostname) will cause legitimate mail to bounce. Testing mode lets you identify issues via TLS-RPT reports without losing mail.
Check Your MTA-STS Configuration
Run a free domain security scan to verify your MTA-STS setup, TLS certificates, and policy file.
Scan Your Domain Browse All Guides