Back to blog
Authentication··14 min read·WillItInbox Team

MTA-STS and TLS-RPT: setup, testing, and failure diagnosis

Publish MTA-STS safely, collect TLS reports, diagnose transport failures, and move from testing to enforcement with evidence.

TLSMTA-STSAuthentication

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.

Use the authentication hub for the adjacent SPF, DKIM, DMARC, and DNS work, then use the MTA-STS checker to validate the transport policy itself.

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

Before changing policy, run the free MTA-STS checker to confirm the DNS signal and HTTPS policy are both reachable from public networks.

StandardPurposeDirection
MTA-STSEnforce TLS to your MX hostsInbound (mail TO you)
TLS-RPTGet reports of TLS failuresInbound reporting
DANE/TLSAAlternative to MTA-STS using DNSSECInbound
MTA-STS vs TLS-RPT — they go together but solve different problems.

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.

mta-sts.txttxt
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.

DNS records
HostTypeValueTTL
_mta-sts.example.comTXTv=STSv1; id=202604191200003600
_smtp._tls.example.comTXTv=TLSRPTv1; rua=tls-report-mailbox3600
MTA-STS announcement and TLS-RPT reporting endpoint.

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, and downgrade attempts. Keep the adjacent MX, TLS, and authentication records under review with the domain monitoring workflow.

FailureLikely causeFix
certificate-expiredMX cert past expiryRenew immediately
certificate-host-mismatchCert SAN doesn't include the MX hostnameReissue with correct SAN
starttls-not-supportedMX doesn't advertise STARTTLSConfigure TLS on the MX
validation-failureCert chain incomplete or untrusted CAInstall full chain
Common TLS-RPT failure types.

Step 4 — Move to enforce

  1. Run in testing mode for at least 4 weeks.
  2. Confirm TLS-RPT reports show no failures from major receivers (Google, Microsoft, Yahoo).
  3. Update mta-sts.txt to mode: enforce and bump the id in DNS.
  4. 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.

Additional guidance: MTA-STS and TLS-RPT Explained: Stop SMTP Downgrade Attacks

MTA-STS and TLS-RPT Explained: Stop SMTP Downgrade Attacks: practical workflow
  1. 01Inspect

    Inspect the DNS and signed-message evidence.

  2. 02Decide

    Confirm alignment and policy behavior.

  3. 03Verify

    Monitor the change before enforcement.

MTA-STS (Mail Transfer Agent Strict Transport Security) is a DNS-and-HTTPS mechanism that tells sending mail servers your domain requires TLS-encrypted delivery to specific MX hosts — blocking STARTTLS downgrade attacks and MX interception. You deploy it with a policy file at https://mta-sts.<domain>/.well-known/mta-sts.txt, a _mta-sts TXT record, and an optional _smtp._tls TLS-RPT record that collects reports of TLS failures.

Roughly speaking, these are the two records most domains skip — and the gap matters. Here's the threat model, the deployment, and the operational traps.

The problem: SMTP's TLS is opportunistic, not enforced

Server-to-server email delivery (one MTA relaying to another over port 25) was designed in an era with no encryption at all. TLS arrived later, bolted on via STARTTLS: the two servers connect in plaintext, exchange capabilities, and — if both support it — upgrade to TLS mid-conversation.

That's called opportunistic TLS: encrypt if possible, deliver in cleartext if not. It's better than nothing, and it does protect against passive surveillance in most cases. But it has a structural weakness. Because the capability exchange happens in plaintext, an attacker in a man-in-the-middle position can:

  1. Strip STARTTLS. The attacker intercepts the connection and removes the STARTTLS advertisement from the server's EHLO response. The sender concludes TLS isn't supported and delivers in cleartext. This is the classic STARTTLS stripping attack, and it's trivial to execute on networks the traffic crosses.
  2. Intercept MX resolution. DNS lookups for MX records are usually unauthenticated (no DNSSEC). An attacker can poison or spoof the MX answer and point the sender at their own server — which happily offers TLS with a self-signed cert, or no TLS at all.

Why doesn't certificate validation save you? Because most MTAs historically did not validate MX server certificates against the recipient domain. The MX host mail.example.com might present a cert for mail.your-esp.net (normal for hosted email), and senders couldn't distinguish "legitimately hosted" from "attacker's box." So the de facto standard became: encrypt opportunistically, ignore certificate mismatches, deliver anyway.

If you want the full background on how STARTTLS and implicit TLS differ mechanically, see STARTTLS vs SSL/TLS for email. The short version: opportunistic STARTTLS protects against passive listeners but not active attackers. MTA-STS exists to close that gap.

How MTA-STS fixes it

MTA-STS, standardized in RFC 8461, lets a receiving domain publish two things:

  • A DNS record (_mta-sts.<domain>) advertising that a policy exists, plus a policy ID and freshness signal.
  • A policy file served over authenticated HTTPS at a fixed URL, declaring which MX hosts are legitimate and whether TLS is mandatory.

A sending MTA that supports MTA-STS (Gmail, Yahoo, Microsoft 365, and most large providers do) fetches and caches the policy. When delivering to your domain, it will only send if:

  • The connection negotiates TLS successfully, and
  • The MX server's certificate is valid, publicly trusted, and matches the recipient domain, and
  • The MX hostname matches a pattern in your published policy.

If any condition fails, a policy in enforce mode tells the sender to bounce the message rather than deliver insecurely. That converts "silent cleartext downgrade" into "loud, visible delivery failure" — which is exactly what you want when the alternative is someone reading your mail.

The DNS record and policy file, line by line

The `_mta-sts` TXT record

dns
_mta-sts.example.com.  IN  TXT  "v=STSv1; id=20260801T010000;"
  • `v=STSv1` — version tag, required, first.
  • `id=` — a policy identifier, max 32 alphanumeric chars. Senders compare the cached id with the current record to decide whether to re-fetch the policy. You must change the `id` every time you update the policy file, or senders will keep using the stale cached version. Date-time strings are the convention for a reason.

The policy file

Served at https://mta-sts.example.com/.well-known/mta-sts.txt — note the mta-sts subdomain, not the apex, and it must be HTTPS with a valid, publicly trusted certificate. Content type is text/plain; the format is key-value lines:

version: STSv1
mode: enforce
mx: mail.example.com
mx: *.example.com
max_age: 604800
  • `version: STSv1` — required first line.
  • `mode:`enforce, testing, or none. The progression path, covered below.
  • `mx:` — one line per permitted MX pattern. Wildcards cover one left-most label: *.example.com matches mail.example.com but not mx1.mail.example.com. Every host in your actual MX record set must match at least one pattern, or senders in enforce mode will reject connections to the unmatched host.
  • `max_age:` — cache lifetime in seconds. 604800 is one week, the common choice. RFC caps it at about a year; keep it long enough that transient fetch failures don't invalidate your policy (senders keep using a cached policy past expiry if they can't re-fetch).

The gotcha hiding in plain sight: the policy is fetched from mta-sts.example.com, which means that subdomain needs a web server (or serverless function, or static host) with a valid TLS certificate, forever. This is an operational dependency most guides gloss over — it's covered in the gotchas section below.

Testing mode first: the sane deployment progression

Never deploy straight to enforce. The correct sequence:

  1. Publish `mode: testing` with a short max_age (e.g., 86400, one day) and TLS-RPT enabled. In testing mode, senders apply the policy but deliver anyway on failure — and report failures via TLS-RPT. This is your observation window.
  2. Watch TLS-RPT reports for 2–4 weeks. You're looking for legitimate senders failing TLS validation against your MX hosts — usually stale MX records, certificate name mismatches, or an ESP-side MX that doesn't match your patterns.
  3. Fix what the reports surface. Update the mx: patterns, fix certificate issues on your MX hosts, clean up decommissioned MX records.
  4. Bump `max_age` to a week or two, confirm reports stay clean.
  5. Flip to `mode: enforce`. Update the policy file, change the id in the DNS record, and keep TLS-RPT running permanently.

Before you publish anything, validate the record and policy file with a checker rather than eyeballing syntax — WillItInbox's free MTA-STS checker fetches both the DNS record and the policy file and flags mismatched MX patterns, certificate problems on the policy host, and mode/max_age sanity issues in one pass.

TLS-RPT: getting reports when TLS fails

MTA-STS tells you what senders enforce. TLS-RPT (SMTP TLS Reporting, RFC 8460) tells you what's actually failing — and it works independently of MTA-STS. Even domains without MTA-STS should publish it.

The `_smtp._tls` record

dns
_smtp._tls.example.com.  IN  TXT  "v=TLSRPTv1; rua=mailto:[email protected]"

That's the whole record. rua takes one or more comma-separated report destinations (mailto: or https: endpoints). Sending MTAs that support TLS-RPT aggregate TLS negotiation outcomes for your domain and send a daily JSON report — the same operational model as DMARC aggregate reports, so if you've built DMARC report processing, TLS-RPT slots right in.

What a report looks like

json
{
  "organization-name": "Example Sender Corp",
  "date-range": { "start-datetime": "2026-08-01T00:00:00Z",
                  "end-datetime": "2026-08-01T23:59:59Z" },
  "contact-info": "[email protected]",
  "report-id": "2026-08-01T00:00:00Z_example.com",
  "policies": [
    {
      "policy": {
        "policy-type": "sts",
        "policy-string": ["version: STSv1", "mode: testing",
                          "mx: mail.example.com", "max_age: 604800"],
        "policy-domain": "example.com",
        "mx-host": ["mail.example.com"]
      },
      "summary": { "total-successful-session-count": 14812,
                   "total-failure-session-count": 3 },
      "failure-details": [
        { "result-type": "certificate-expired",
          "sending-mta-ip": "203.0.113.10",
          "receiving-mx-hostname": "mail.example.com",
          "failed-session-count": 3 }
      ]
    }
  ]
}

The result-type values are the actionable part: starttls-not-supported, certificate-host-mismatch, certificate-expired, certificate-not-trusted, validation-failure, sts-policy-fetch-error, and a few others. Each maps to a specific fix — expired cert on an MX, policy file unreachable, MX hostname typo.

The volume reality: if you use a major mailbox provider (Google Workspace, Microsoft 365) rather than self-hosted MX, reports will mostly show zero-failure days, which is itself valuable — it's confirmation that nobody is actively interfering with your TLS. If you self-host MX, expect noise initially.

DANE: the alternative path worth knowing about

DANE (DNS-based Authentication of Named Entities, RFC 6698) solves the same problem through a different mechanism: you publish TLSA records in DNS (signed with DNSSEC) that pin the certificate your MX hosts present. Senders validating via DANE check the TLS handshake against the DNS-published fingerprint.

Trade-offs, briefly:

  • DANE has no policy-file hosting dependency and no caching lag — but it requires DNSSEC, which many registrars and DNS providers still make painful, and which adds its own operational fragility (a botched key rollover breaks all your DNS, not just TLS validation).
  • MTA-STS needs no DNSSEC and is supported by the largest mailbox providers (Gmail, Yahoo, Microsoft all check it). Its weak point is the DNS record itself isn't authenticated — an attacker could theoretically suppress the _mta-sts record on first contact. The caching model mitigates this: once a sender has your policy cached, suppressing the DNS record doesn't help the attacker until the cache expires.

They're not exclusive — some security-sensitive domains run both. For most operators, MTA-STS is the pragmatic choice: better sender support, no DNSSEC prerequisite.

Operational gotchas that bite in production

  • The policy host is a permanent dependency. mta-sts.example.com must serve the file over valid HTTPS indefinitely. Let the certificate lapse or the host die, and senders with expired caches fall back to policy-fetch failure behavior. Put the file on durable static hosting and monitor it like production infrastructure.
  • Forgetting to bump the `id`. Update the policy file without changing the id in the TXT record and senders keep the stale cache until max_age runs out. Automate id generation (timestamp) if you touch the policy more than rarely.
  • MX pattern mismatches. Your MX records are aspmx.l.google.com and friends (Google Workspace) but your policy says mx: *.example.com — enforce mode would reject Gmail's own delivery infrastructure. Your mx: patterns must match your actual MX record set, which for hosted email means your provider's hostnames. Google and Microsoft publish recommended patterns.
  • Certificate validity on MX hosts. If you self-host MX, the certs must be publicly trusted (no self-signed), unexpired, and matching the MX hostname. Managed providers handle this; self-hosted operators must automate renewal.
  • Policy caching lag. With a one-week max_age, a bad policy can haunt you for a week. This is why testing mode with short max_age comes first.
  • Sending vs receiving asymmetry. MTA-STS protects mail sent to you. Your own outbound encryption posture is a separate question — senders control their side; you control yours via your provider's settings.

Monitoring drift over time

Like DMARC, MTA-STS fails silently when it rots. The certificate on the policy host expires, someone restructures DNS and drops the _mta-sts record, an MX migration invalidates the patterns — and the only symptom is TLS-RPT failures or, worse, nothing at all.

WillItInbox's DMARC and domain monitoring tracks your MTA-STS and TLS-RPT records alongside SPF, DKIM, DMARC, and BIMI, alerting when records change, disappear, or when the policy file stops responding — so a DNS cleanup on Friday doesn't quietly downgrade your transport security for a month. Re-run the MTA-STS checker after any MX or DNS provider change; it takes seconds.

If you're still working through the broader authentication stack, MTA-STS sits at the end of the queue: get SPF, DKIM, and DMARC enforced first (the DMARC rollout playbook covers that path), then layer transport security on top. And when you're validating whether a delivered message actually traveled encrypted, the Received header chain tells the story — the email header analysis guide shows you how to read it.

Run the MTA-STS checker to verify DNS and HTTPS publication. Use TLS-RPT results to diagnose real transport failures before changing from testing to enforce mode.

Frequently asked questions

Last updated June 13, 2026.

Sources reviewed

Factual review: June 13, 2026 by WillItInbox Editorial.

Keep reading