MTA-STS Checker
Verify your MTA-STS DNS record and policy file. MTA-STS enforces TLS encryption for inbound email delivery to your domain.
Try an example: google.com ยท fastmail.com ยท mailbox.org
Validation results
How this MTA-STS checker works
MTA-STS (RFC 8461) tells sending mail servers two things: use TLS for delivery to your domain, and refuse to deliver if the certificate doesn't match the MX hostname. Without it, anyone on the path between sender and receiver can strip the STARTTLS upgrade. The mail still arrives. It just arrives in plaintext, and nobody on either end notices.
Type a domain above and the checker walks the same path a real sender would. First it reads the _mta-sts TXT record to confirm a policy is published and to pick up the id= token senders use as the cache key. Then it fetches the policy file:
https://mta-sts.example.com/.well-known/mta-sts.txt
Every directive gets validated against the spec. The mx: entries get cross-referenced against the actual MX records. A policy that still lists an old Google MX while production moved to Microsoft 365 will show up here, because senders running in enforce will reject mail to the new host.
What the policy file has to look like
RFC 8461 ยง3.2 and ยง3.3 are picky, and strict senders refuse policies that break the rules. The checker confirms:
Content-Type: text/plain ← not text/html
No redirects ← fetched directly
No UTF-8 BOM ← plain ASCII bytes
LF or CRLF line endings ← never bare CR
Lines under 1024 bytes ← spec ceiling
Unknown directives get called out as likely typos. Once the file passes, the checker looks at the certificate on the mta-sts. host: it walks the WebPKI chain, confirms the SAN covers the policy host, and reports days to expiry. A cert with under 14 days left earns a warning.
The silent-expiry problem
A silently expired policy certificate is one of the most common ways MTA-STS regresses. Cached senders keep enforcing until max_age elapses, then they quietly fall back to opportunistic STARTTLS. The recipient's logs look fine. The certificate looks broken if anyone bothered to check it, but nothing alerts. This is exactly the failure mode MTA-STS was meant to prevent, and it's the one MTA-STS itself can introduce if you stop watching.
Our take: treat the mta-sts. host the same way you treat your main web certificate. Auto-renew it, and put a monitor on the expiry so the alarm fires before the cache does.
Cross-checks the tool runs alongside
Two extras run alongside the policy fetch. The first looks for TLS-RPT at _smtp._tls.<domain>. Without TLS-RPT, MTA-STS is enforcing a policy you can't observe: senders refuse delivery on a cert mismatch, and the only feedback channel is a user complaining. The second looks for DANE on the same MX hosts.
DANE and MTA-STS cover the same threat through different trust models. DANE anchors trust in DNSSEC. MTA-STS anchors it in WebPKI. Big senders split: Google and Microsoft lean MTA-STS, academic and operator networks lean DANE. Publishing both covers the most ground.
Where to go next
The grade rolls A through F with plain-English reasons and a row of signal chips for each compliance check. If nothing is published yet, the tool emits a copy-pasteable starter policy. The mx: patterns in that policy come from your actual MX records, so verify those line up first with the MX inspector before flipping enforce on. For the underlying record syntax, see the MTA-STS TXT record reference.
Frequently Asked Questions
Common questions about MTA-STS and email transport encryption.
What does "enforce" mode actually do?
The mode field takes three values.
testing applies the policy but lets the mail through on failure, with a TLS-RPT entry describing what would have been rejected. enforce rejects mail to any MX that doesn't match the policy or fails certificate validation. none withdraws the policy without breaking caches that still hold it. Use that one during a migration off MTA-STS, not as a starting point.
Our take: sit in testing for at least a week so the longest cache TTLs all expire and you get a clean TLS-RPT signal. Then flip to enforce once the reports show zero failures.
How do I fix "MX records do not match"?
Every hostname your MX query returns has to be covered by an mx: line in the policy file. If you migrated from Google to Microsoft 365 and the policy still says aspmx.l.google.com, every sender in enforce rejects mail to the new MX.
The fix is two steps: edit mta-sts.txt to match the live MX set, then bump the id= in the _mta-sts TXT record. The ID is the cache key. Senders only refetch when it changes.
How long does propagation take?
The DNS TXT record propagates in minutes. The policy file behind it is a different story: senders cache the body for max_age seconds, and typical values are 86400 (a day) or 604800 (a week).
A policy change doesn't take full effect until every sender's cached copy expires. Use max_age: 86400 during rollout so mistakes wash out within a day, then raise it to a week once the policy is stable.
What happens if the mta-sts certificate expires?
Spec-compliant senders stop fetching the policy. Cached copies keep enforcing until max_age runs out, then those senders fall back to opportunistic STARTTLS. That is the exact failure mode MTA-STS exists to prevent.
The failure is silent. Nothing changes for the recipient until a sender reports it via TLS-RPT, and most senders batch those reports into one JSON file a day.
What to do: treat the mta-sts.<domain> certificate the way you treat your main web certificate. Monitor expiry. Auto-renew well ahead. After every renewal, confirm the chain and SAN coverage didn't break. The checker above flags certs with under 14 days left.
Should I also publish DANE?
If your zone is DNSSEC-signed, yes. DANE (RFC 7672) and MTA-STS cover the same threat (downgraded TLS on SMTP delivery) through different trust models.
DANE anchors trust in DNSSEC. You publish a TLSA record fingerprinting the certificate, and senders that validate DNSSEC trust that instead of the public CA system. MTA-STS anchors trust in WebPKI, leaning on the same CAs that sign your HTTPS certificates.
Big senders split along those lines. Google and Microsoft favour MTA-STS. Academic and operator networks favour DANE. Publish both and you cover the most ground. See the DANE checker.
Why does the policy ID need to change?
The id= value in the _mta-sts TXT record is the cache key. Senders hold the policy file body for max_age seconds, but they refetch the moment they see a new ID.
Edit the policy file and leave the ID alone and senders keep using the old cached copy until its TTL expires, which can be a full week. Your fix sits idle.
The conventional pattern is a current timestamp like:
id=20260603105500
It sorts chronologically and you can read it without consulting a changelog. The checker above parses that shape and tells you how old the ID is.