Skip to content
wiki · technical reference

MTA-STS

Force inbound mail to your domain to use TLS. Closes the downgrade-attack gap that opportunistic STARTTLS leaves wide open.

~6 min read

The problem MTA-STS solves

SMTP between mail servers traditionally negotiates TLS opportunistically through STARTTLS. The connecting server says "do you support TLS?" The receiving server says "yes, here's my cert." They upgrade the connection. Mail flows encrypted. If the cert is bad or TLS isn't offered, the connecting server typically falls back to plaintext.

That fallback is the problem. An attacker positioned between two mail servers can strip the STARTTLS offering from the receiving server's greeting, forcing the connecting server to deliver in plaintext. The attacker reads everything: subjects, body, attachments. From the connecting server's view, nothing went wrong. TLS just wasn't available.

This is the STARTTLS downgrade attack. It was used at scale by ISPs in some jurisdictions in the early 2010s to inspect cross-border mail. MTA-STS was built to close it.

How MTA-STS works

MTA-STS lets a domain owner publish a policy that says: "when delivering mail to my domain, TLS is required, here are the valid MX hostnames, and don't fall back to plaintext if anything fails."

The policy lives in two places:

  • A DNS TXT record at _mta-sts.<domain>. Contains the version (v=STSv1) and a policy ID (id=...). The ID changes whenever the policy file changes.
  • A policy file at https://mta-sts.<domain>/.well-known/mta-sts.txt. Contains the actual policy: enforcement mode, allowed MX hostnames, max-age.

When a sending MTA wants to deliver to your domain, it checks DNS for the TXT record, fetches the policy file via HTTPS, validates the policy, caches it for the duration in max_age. If the cached policy says "enforce TLS to these MX hostnames," the sending MTA refuses to deliver in plaintext or to any unauthorised MX, even if the receiving server's STARTTLS gets stripped or its cert is bad.

The policy file format

Plain text at /.well-known/mta-sts.txt on the mta-sts.<domain> subdomain. Typical content:

version: STSv1
mode: enforce
mx: mail.example.com
mx: mail2.example.com
mx: *.mailservers.example.com
max_age: 86400

Decoded:

  • version: STSv1. Always STSv1 in current use.
  • mode: enforce. Three values: none (declares the domain has been MTA-STS-tested but enforces nothing), testing (sending MTA reports failures via TLS-RPT but still delivers), enforce (sending MTA refuses to deliver if policy fails).
  • mx: entries. One or more allowed MX hostnames. Wildcards (*.mailservers.example.com) are permitted.
  • max_age. How long the policy can be cached, in seconds. 86400 (one day) is a common starting value. Production deployments often go to 604800 (one week) once stable.

The DNS TXT record

The TXT record at _mta-sts.<domain> tells sending MTAs that an MTA-STS policy exists and gives them the policy ID:

_mta-sts.example.com.    IN    TXT    "v=STSv1; id=20260101-1"

The id is opaque to senders; they use it to detect when the policy has changed and re-fetch. Convention is a date-based ID like 20260101-1, incremented on every policy file update.

Update the policy file without updating the ID? Cached policies don't refresh. Sending MTAs keep using the old policy until their cache expires. Update the ID without updating the policy? Harmless but pointless. Both moves are common mistakes.

The three enforcement modes (and the ramp between them)

MTA-STS has three modes. Production deployments ramp through them in order.

mode: none. Declares the domain has been MTA-STS-evaluated but enforces nothing. Use this only as a transitional step. Not as a final state. none tells senders "I'm thinking about MTA-STS but haven't committed."

mode: testing. Sending MTAs check the policy and report violations via TLS-RPT, but still deliver. Use this for the first 30 days of an MTA-STS deployment to find any senders that would be blocked under enforce mode (typically: very old senders without MTA-STS support, senders with broken TLS configs).

mode: enforce. The production state. Sending MTAs refuse to deliver if any policy condition fails. TLS unavailable, cert invalid, MX not in the list, MX cert doesn't match its hostname. Move here once your TLS-RPT reports show legitimate senders are reaching you cleanly under testing mode.

The ramp from testing to enforce typically takes 30-60 days and depends on what TLS-RPT shows. Senders sometimes have transient TLS issues (cert renewals, MX migrations) that look like policy failures but aren't structural. Wait until the failure rate is consistently low before promoting.

To validate your current MTA-STS configuration (DNS record, policy file, MX alignment, mode): use our free MTA-STS Validator. To parse incoming TLS-RPT JSON reports: use the TLS-RPT Parser.

TLS-RPT: the visibility companion

TLS-RPT (RFC 8460) is the reporting layer for MTA-STS. It tells you which senders successfully connected with TLS, which failed, and why. Without TLS-RPT you're flying blind during the testing phase.

TLS-RPT is a separate DNS TXT record at _smtp._tls.<domain>:

_smtp._tls.example.com.    IN    TXT    "v=TLSRPTv1; rua=mailto:tls-rpt@example.com"

Sending MTAs that support TLS-RPT send daily aggregate reports to the rua= address. Reports are JSON. They summarise the sender's TLS connection attempts to your domain: total sessions, successful sessions, failed sessions, and for failures, the reason (no TLS offered, cert validation failure, policy mismatch, etc).

This is the data that lets you safely move from testing to enforce mode. If failure rates are near zero across major senders (Google, Microsoft, Yahoo) and only a handful of legacy senders are failing, you can promote without breaking real inbound mail.

How MTA-STS interacts with DANE

DANE (DNS-based Authentication of Named Entities) is an alternative TLS-enforcement mechanism using DNSSEC and TLSA records instead of HTTPS-fetched policy files. The two coexist. Some senders prefer one over the other.

Practical differences:

  • DANE requires DNSSEC. No DNSSEC, no DANE. MTA-STS works without DNSSEC.
  • MTA-STS requires HTTPS. Policy file lives at an HTTPS URL, so you need a valid TLS cert on the mta-sts subdomain.
  • DANE pins individual cert hashes. MTA-STS pins MX hostnames and trusts the regular CA system for cert validation.
  • Major senders support both. Google, Microsoft, Apple, Yahoo all support both. Most production deployments publish both.

For a sender without DNSSEC, MTA-STS alone is a strong improvement. Adding DANE later once DNSSEC is in place is straightforward.

MTA-STS in 2026: production deployment patterns

MTA-STS deployment through 2024-2026 has settled into a small number of production patterns that work reliably. The patterns below capture what we have seen produce zero-downtime deployments versus what produces predictable issues.

The standard production pattern: deploy the policy file at mta-sts.yourdomain.com/.well-known/mta-sts.txt in testing mode initially, run for 14-30 days with TLS-RPT monitoring to identify any failures, transition to enforce mode only after aggregate reports show clean operation. The total deployment timeline runs 4-6 weeks from start to enforce mode for typical operations; longer if the initial testing surfaces issues that need remediation before enforce can be safe.

The policy file content for production: version: STSv1, mode: testing initially transitioning to mode: enforce, mx: listing all current MX hostnames including patterns for redundant infrastructure, max_age: set to a short value during testing (1-7 days for quick policy update propagation) and longer in production (typically 604800 for one week or 2592000 for one month). The max_age controls how long receivers cache the policy; longer values reduce receiver-side fetch load but slow propagation of policy changes.

The DNS record content: v=STSv1; id=YYYYMMDDHHMMSS where id must change every time the policy file changes. The id value is what tells receivers their cached policy is stale and needs refresh. Production deployments need consistent id-update discipline; policy changes without id updates produce situations where some receivers see the old policy and others see the new one based on their cache expiration times.

The HTTPS infrastructure serving the policy file matters for reliability. The policy server should have very high availability because policy fetch failures during enforce mode can block legitimate mail delivery. CDN hosting (Cloudflare, Fastly, CloudFront) is the standard production pattern; self-hosted policy servers are workable but produce more single-point-of-failure exposure than CDN-fronted alternatives.

MTA-STS versus DANE: when to use each

MTA-STS and DANE both provide authenticated TLS for inbound mail but through different mechanisms. The choice between them produces different operational tradeoffs and many operators end up using both for different reasons.

MTA-STS uses HTTPS-served policy files plus DNS records. The HTTPS dependency means deployment requires certificate management on the policy serving subdomain plus DNS configuration. Adoption has been broader than DANE because the deployment path is more accessible to operators without DNSSEC infrastructure. Sender-side support is near-universal among major receivers as of 2026.

DANE uses DNSSEC-signed TLSA records to bind certificates to DNS. The DNSSEC dependency means deployment requires DNSSEC infrastructure (signed zone, properly configured DNS servers, key management). Adoption has been narrower than MTA-STS because DNSSEC deployment remains limited despite years of advocacy. Where DANE is deployed, it provides stronger security guarantees because the certificate binding does not depend on a separate HTTPS infrastructure that could be compromised.

Most operators in 2026 deploy MTA-STS because the deployment path is more practical and the security benefits over plain STARTTLS are adequate for most threat models. Operators with stronger security requirements or pre-existing DNSSEC infrastructure additionally deploy DANE; when both are present, sending MTAs that support both typically prefer DANE.

For senders making the deployment decision: MTA-STS is the right starting point. DANE is appropriate to add later when DNSSEC infrastructure justifies it or when threat model requires the stronger binding. Operators should not delay MTA-STS deployment waiting for DANE; the security benefit of MTA-STS is real and the marginal additional benefit of DANE is small for most use cases.

MTA-STS for forwarding and relay scenarios

Standard MTA-STS deployment covers the simple case of inbound mail to the domains MX hosts. More complex scenarios involve mail forwarding, relay infrastructure, and multi-hop delivery paths. The handling for each varies and matters for getting MTA-STS deployment right in non-trivial configurations.

Mail forwarding (mailbox forwards to another address): the MTA-STS policy applies to the original recipient domain. After the forwarding happens, the mail flows to whatever destination the forward target indicates with whatever TLS policy applies to that destination. The forwarder needs to respect MTA-STS policies of its forwarding destinations independently of its own MTA-STS policy as a recipient.

Mailing list software (recipient is a list address): similar pattern to forwarding. MTA-STS policy of the list domain applies to inbound mail to the list. The list software then distributes to subscribers; the distribution to each subscriber respects that subscribers MTA-STS policy as a recipient.

Relay infrastructure (mail passes through intermediate MTAs): each hop in the chain operates as both sender and recipient. The intermediate MTA needs to respect the next-hop MTA-STS policy as a sender, and may publish its own MTA-STS policy as a recipient for whoever is sending to it. The chain works correctly when each hop handles its sender and recipient roles independently.

Smart host configurations (sender routes through specific MTAs): the smart host operates as the sender from the perspective of the final receiver. The smart host needs MTA-STS-aware sending behavior; senders configured to route through smart hosts should verify the smart host respects MTA-STS policies of destinations.

For each scenario, the standard deployment guidance applies to the operators own infrastructure; the senders own MTA-STS policy covers inbound to their MX hosts, and the senders sending infrastructure should respect MTA-STS policies of outbound destinations. The complexity in multi-hop scenarios is verifying each hop in the chain implements MTA-STS correctly, which requires coordination with the operators of intermediate infrastructure.

Common MTA-STS misconfigurations

Production MTA-STS deployments encounter specific misconfigurations regularly. The patterns below capture the misconfigurations that surface most often and how operators identify them.

Misconfiguration 1: certificate mismatch on the mta-sts subdomain. The HTTPS policy server presents a certificate that does not include the mta-sts subdomain as a valid name. Senders fetching the policy get certificate errors and treat the policy as unreachable. Diagnostic indicator: TLS-RPT reports showing sts-policy-fetch-error from multiple senders. Fix: issue a certificate that explicitly includes the mta-sts subdomain or use a wildcard certificate covering it.

Misconfiguration 2: id value not incremented when policy changes. The policy file is updated but the DNS id value is not changed. Receivers continue using the cached old policy until cache expiration, which can take days or weeks. Diagnostic indicator: policy changes do not seem to take effect, receivers continue applying old behavior. Fix: increment the id value every time the policy file changes; the value can be any string that changes, but YYYYMMDDHHMMSS is the standard convention.

Misconfiguration 3: max_age too short for production. The policy max_age is set to a very short value (less than 1 day) that produces excessive policy refresh load on the receivers side. Some receivers may treat very short max_age as suspicious. Fix: use max_age values appropriate for production (604800 for one week is standard) once the policy is stable.

Misconfiguration 4: mx allowlist incomplete. The policy mx values do not include all current MX hostnames, or include patterns that do not match the actual MX hostnames. Senders attempting delivery to MX hosts not in the allowlist receive mx-mismatch failures under enforce mode. Fix: ensure the mx allowlist includes all MX hostnames with patterns that match exactly (wildcards work but must be specified correctly).

Misconfiguration 5: backup MX not configured for STARTTLS. The primary MX supports STARTTLS correctly but a backup MX added for redundancy does not. Senders falling back to the backup MX get starttls-not-supported failures. Fix: ensure all MX hosts in the allowlist support STARTTLS with valid certificates; backup MX infrastructure needs the same TLS configuration as primary.

Troubleshooting

TLS-RPT reports show legitimate senders failing under enforce mode
Check the failure reason in the report. "MX not in policy" usually means you added a new MX without updating the policy file (and the policy ID). "Cert validation failure" means your MX cert is invalid or self-signed. "STARTTLS not offered" means the receiving server has a TLS configuration issue.
Policy file fetch returns 404
The policy file must be at https://mta-sts.<domain>/.well-known/mta-sts.txt, served with a valid TLS cert for that subdomain. Verify the file exists and that the mta-sts subdomain has its own HTTPS configuration. The file must be served fresh; avoid CDN caching that prevents updates from propagating.
Some senders ignore my MTA-STS policy entirely
Not every sending MTA supports MTA-STS. Old or self-rolled MTAs may not check the policy at all. Expected behaviour. MTA-STS is opt-in for senders. TLS-RPT reports tell you which senders are checking and which aren't. Most major senders (Google, Microsoft, Yahoo, Apple, ProtonMail, Fastmail) implement it.
Cached old policy is causing rejections after I updated MX servers
You forgot to update the policy ID. Sending MTAs cache the policy for max_age and detect updates by ID change. Increment the ID in the DNS TXT record any time you change the policy file. Senders re-fetch on next attempt and use the new policy.
Promoted to enforce mode and now mail from one specific sender bounces
That sender either doesn't support MTA-STS or has a TLS misconfiguration. Check TLS-RPT for the specific failure. If the sender is important and the failure is on their side, drop back to testing mode and contact the sender to coordinate. Don't leave enforce mode permanently because of one failing sender. That defeats the purpose.
My MTA-STS deployment is in testing mode but I am not receiving any TLS-RPT reports
Three potential issues. First, the TLS-RPT DNS record may be missing or misconfigured: verify _smtp._tls.yourdomain.com publishes the TLSRPTv1 record correctly. Second, the rua mailbox may have aggressive filtering: verify the mailbox accepts ARF-formatted messages and JSON attachments. Third, your sending volume to your domain may be too low for senders to generate reports: TLS-RPT reports only flow from senders with material connection volume to your infrastructure. If volume is low, expect fewer reports; this is normal rather than a deployment issue.
I transitioned to enforce mode and now some legitimate inbound mail is being blocked
Immediate rollback to testing mode while diagnosing. The transition to enforce should only happen after TLS-RPT shows clean aggregate reports for 14-30 days; transition before that produces predictable blocking. Look at TLS-RPT reports for the failure categories now blocking mail. Common causes: a sender that was failing in testing mode without you noticing because the failures did not block mail, certificate issues on one of your MX hosts that started causing failures recently, mx allowlist incomplete. Address the specific failure categories before transitioning back to enforce.

Related entries