| 14 min read

MTA-STS not working? Fix the 7 errors senders report

MTA-STS breaks when DNS, HTTPS policy hosting, and MX TLS drift out of sync. This troubleshooting guide covers seven failures, the records to check first, and the commands that expose them.

ML
Marc Lelu
MTA-STS not working? Fix the 7 errors senders report

We launched Receiver Shield a few weeks ago. Since then we have been processing TLS-RPT reports across our customer base, reading community forum threads, and reviewing broken MTA-STS deployments.

The protocol is small: two DNS TXT records, one HTTPS policy file, and sometimes one CNAME if a hosted policy service serves the file for you. The failures are usually operational. A policy can load in your browser and still fail for sending MTAs. One record can change while another stays stale. A bad cached policy may not hurt until days later, when a sender reuses it during delivery.

Use this as a triage order. Each failure links to a deeper troubleshooting guide with diagnosis commands and fixes.

The records to check first

Before chasing an individual TLS-RPT failure, verify the three public surfaces.

Your MTA-STS discovery record is a DNS TXT record at _mta-sts:

_mta-sts.example.com. 3600 IN TXT "v=STSv1; id=20260531090000Z;"

v=STSv1 must be the first tag. id is required by RFC 8461, must be 1 to 32 alphanumeric characters (RFC 8461 §3.1), and must change whenever the served policy content changes. If you edit mta-sts.txt but leave id unchanged, senders can keep using the old cached policy until max_age expires.

The policy file must be available at this exact HTTPS URL:

https://mta-sts.example.com/.well-known/mta-sts.txt

A minimal testing policy looks like this:

version: STSv1
mode: testing
mx: mx1.example.com
mx: *.example.net
max_age: 86400

mode is one of testing, enforce, or none. Use one mx: line per allowed MX pattern, except when mode: none is used. A wildcard only replaces the full left-most label, so *.example.net matches mx1.example.net but not mx1.mail.example.net.

TLS-RPT uses a separate DNS TXT record:

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

rua is required. RFC 8460 allows both mailto: and https: report destinations. You can list multiple destinations separated by commas, but do not assume every sending provider will deliver a report to every destination.

Start with these DNS checks:

dig TXT _mta-sts.example.com +short
dig TXT _smtp._tls.example.com +short
dig MX example.com +short
dig CNAME mta-sts.example.com +short

Fetch the policy without following redirects, and surface both the status line and Content-Type header:

curl -sS -D - --max-time 10 https://mta-sts.example.com/.well-known/mta-sts.txt -o /dev/null

That prints only the headers. Drop -o /dev/null to see the body as well.

Do not use curl -L for this check. A browser-style redirect can hide the condition that makes policy fetches fail for sending MTAs. RFC 8461 §3.3 is explicit: HTTP 3xx redirects MUST NOT be followed, and only HTTP 200 is a valid response.

Check the certificate on the mta-sts subdomain itself:

openssl s_client -connect mta-sts.yourdomain.com:443 -servername mta-sts.yourdomain.com 2>/dev/null \
  | openssl x509 -noout -subject -dates -ext subjectAltName

This is distinct from the MX server certificate check covered in issue 3 below.

1. sts-policy-fetch-error: the policy file is unreachable

TLS-RPT reports label this sts-policy-fetch-error (RFC 8460 §4.3.2.2). The sending server tried to fetch https://mta-sts.yourdomain.com/.well-known/mta-sts.txt and got something other than HTTP 200 with the policy content.

Typical causes:

  • Wrong path. The file must be at /.well-known/mta-sts.txt, not /mta-sts.txt or anywhere else.
  • HTTP redirect. RFC 8461 §3.3 prohibits following redirects. If the HTTPS policy URL redirects to another host, path, or challenge page, some senders get a 301 and give up. The policy works in your browser (which follows redirects) but fails for MTAs (which must not).
  • Cloudflare Browser Integrity Check. Cloudflare’s BIC blocks requests with non-browser User-Agent strings. Mail servers use agents like libwww-perl/6.68. The policy loads fine when you test it in Chrome, but MTAs get a challenge page instead of the policy file.
  • GitHub Pages. Jekyll ignores directories starting with a dot. If you host on GitHub Pages without a .nojekyll file in the repository root, the /.well-known/ path returns 404.
  • Expired certificate on the mta-sts subdomain. The mta-sts subdomain needs a valid CA-signed TLS certificate. If your Let’s Encrypt renewal did not include that subdomain, the certificate can expire while the rest of the site still works.

The diagnosis is always the same: check the status code and Content-Type first.

curl -sS -D - --max-time 10 https://mta-sts.yourdomain.com/.well-known/mta-sts.txt -o /dev/null

If that does not return HTTP 200 and Content-Type: text/plain, start there.

Policy file format requirements (causes of sts-policy-invalid)

A policy that returns HTTP 200 can still produce sts-policy-invalid (RFC 8460 §4.3.2.2) if the content itself is malformed.

Line endings cause more worry than failures. The prose of RFC 8461 §3.2 describes CRLF-separated key/value pairs, but the ABNF in the same section defines the terminator as LF / CRLF, so a Unix-generated file with bare LF is syntactically valid and conformant parsers must accept it. A validator that flags LF-only line endings is stricter than the spec. The format problems that actually produce sts-policy-invalid are malformed keys, a missing mx line, and out-of-range max_age values.

Content-Type is another. RFC 8461 §3.2 says senders SHOULD validate that the media type is text/plain. A server returning text/html or application/octet-stream can cause fetch rejection.

max_age must stay within range. The maximum value is 31557600 seconds (RFC 8461 §3.2). Google Workspace additionally requires max_age to be at least 86400 seconds and recommends 604800 to 1209600 during testing.

Redirects cause the same problem as with the fetch itself: RFC 8461 §3.3 says HTTP 3xx redirects MUST NOT be followed, so the canonical URL must serve the file directly.

If you do not want to run the policy host yourself, Receiver Shield serves it on the Pro plan. You point one CNAME at DMARCTrust; we handle the HTTPS endpoint, Content-Type, line endings, and certificate.

Our policy fetch failures guide walks through each cause with the exact fix.

2. “The MX host does not match any MX allowed by the STS policy”

This is the verbatim error Google’s postmaster tools and many validators surface when the mx: lines in your policy file do not match your actual MX DNS records. RFC 8460 §4.3 does not define a result type named mx-mismatch. What actually appears in TLS-RPT JSON is certificate-host-mismatch (RFC 8460 §4.3.1) when the mismatch is caught at the TLS handshake, or no delivery attempt at all when the MX host is simply not covered by the policy. Third-party validators label this with phrases like “uncovered MX records” or “MX mismatch” as a convenience label, not an RFC-defined type.

In enforce mode, senders refuse to deliver to any MX host not listed in the policy. Provider MX naming is where policies age badly. Managed providers can publish tenant-specific or regional hostnames, and a policy copied from a generic guide may not match what your domain actually uses today.

Microsoft 365 assigns MX records like yourdomain-com.mail.protection.outlook.com. For domains whose MX points directly to Exchange Online, use:

mx: *.mail.protection.outlook.com

Do not use mx: mail.protection.outlook.com; it does not match the tenant subdomain. Listing one exact tenant hostname can work today but is brittle if the MX target changes.

Google Workspace currently recommends smtp.google.com for new MX setup, while legacy aspmx... values remain supported. Do not copy a generic MTA-STS policy from an old guide. Run:

dig MX yourdomain.com +short

Then include the actual Google MX host or wildcard pattern your domain uses in the policy. For example, a domain whose MX target is smtp.google.com needs:

mx: smtp.google.com

Fastmail publishes two official MX records:

mx: in1-smtp.messagingengine.com
mx: in2-smtp.messagingengine.com

We did not find a current official Fastmail MTA-STS setup guide while updating this post. Treat those MX records as the DNS baseline, then verify STARTTLS and certificate behavior yourself.

Full diagnosis and per-provider patterns are in our MX and certificate mismatches guide.

3. certificate-host-mismatch: TLS cert does not cover the MX hostname

TLS-RPT reports show certificate-host-mismatch (RFC 8460 §4.3.1). The TLS certificate presented by your mail server during the SMTP STARTTLS handshake does not include the MX hostname in its Subject Alternative Names.

That certificate is separate from the certificate on the mta-sts subdomain in issue 1. This check is about the actual mail server that receives email.

Common scenario: your hosting provider’s mail server has a certificate for mail.hostingprovider.com, but your MX record points to mail.yourdomain.com. The certificate does not cover your hostname, so MTA-STS validation fails.

Diagnose it with:

printf 'QUIT\r\n' | openssl s_client -starttls smtp \
  -connect mail.yourdomain.com:25 \
  -servername mail.yourdomain.com \
  -verify_hostname mail.yourdomain.com \
  -verify_return_error

Then inspect the certificate names:

printf 'QUIT\r\n' | openssl s_client -starttls smtp \
  -connect mail.yourdomain.com:25 \
  -servername mail.yourdomain.com 2>/dev/null |
  openssl x509 -noout -subject -issuer -dates -ext subjectAltName

If your hostname is not in the SAN list, contact your mail hosting provider. Large managed providers usually publish MX hostnames with matching STARTTLS certificates, but you should still verify the exact hostname your domain uses.

Our MX and certificate mismatches guide covers incomplete certificate chains and missing STARTTLS as well.

4. The policy ID is not updated after a change

This one is easy to miss because nothing fails at the moment you make the change.

MTA-STS requires three things to stay in sync:

  1. Your actual MX DNS records
  2. The mx: entries and mode in your mta-sts.txt policy file
  3. The id value in your _mta-sts DNS TXT record

When you change the policy file (for example, switching from mode: testing to mode: enforce), you must also change the id in the DNS TXT record. Senders cache the policy for max_age seconds. They only re-fetch when they see a new id. If the id stays the same, senders keep using the old cached policy.

With max_age: 604800 (7 days), your fix may not take effect for up to a week. With max_age: 2592000 (30 days), you may be waiting a month.

That is why Receiver Shield auto-generates the policy ID from the policy content. When you edit the policy in the dashboard, the id updates automatically. You still need to update your DNS TXT record, but the dashboard tells you when it is out of sync.

Our enforce mode and rollback guide covers the three-point sync rule in detail.

5. Jumping to enforce mode too early

Going straight to mode: enforce turns testing mistakes into delivery failures.

Microsoft Exchange Online documents specific NDR (non-delivery report) codes when MTA-STS enforcement blocks delivery, including:

  • 5.4.8 for MX validation failure
  • 5.7.5 for remote certificate validation failure

If you see these bounce codes in your logs, enforce mode is rejecting mail from senders that cannot meet the TLS requirements. The immediate fix is to switch back to mode: testing, bump the id, and investigate.

max_age has traps in both directions during rollout:

  • Too high on first deploy. Some guides show max_age: 31557600 (1 year). If anything is misconfigured, senders who cached the broken policy keep using it for up to a year. Keep testing values conservative and increase once you are confident. Google Workspace documentation allows max_age from 86400 to 31557600 seconds and recommends 604800 to 1209600 seconds while testing.
  • Too low. Google requires max_age to be at least 86400 seconds. If you set max_age: 3600 for quick testing, Google treats the policy as invalid.

Our enforce mode and rollback guide shows the emergency rollback sequence.

6. TLS-RPT reports are not arriving

You publish the _smtp._tls DNS record, wait a few days, and nothing arrives. This is normal and does not mean something is broken.

TLS-RPT reports come from the sending side. Only mail servers that have implemented RFC 8460 will send you reports. If your domain does not receive much email from reporting senders such as Google and Microsoft, you will see few reports.

A few things to rule out before blaming DNS:

  • Wrong rua address. A typo in the mailto: value. Check with dig TXT _smtp._tls.yourdomain.com +short.
  • Reports landing in spam. TLS-RPT reports often arrive as compressed JSON attachments. If your helpdesk or mailbox rules quarantine unknown .json.gz files, the reports may be arriving but never reaching the person who expects them.
  • Multiple destinations. RFC 8460 allows multiple comma-separated rua destinations, but senders are not required to guarantee delivery to every destination. Put your monitoring address first and test that reports arrive there.

TLS-RPT result types: what each one means

When reports do arrive, the table below maps each result type string to its RFC 8460 §4.3 definition and the most likely cause.

Result type RFC 8460 section What happened Likely cause Debug command
sts-policy-fetch-error §4.3.2.2 Sender could not fetch the policy file HTTP non-200, redirect, bad cert on mta-sts subdomain curl -sS -D - https://mta-sts.DOMAIN/.well-known/mta-sts.txt -o /dev/null
sts-policy-invalid §4.3.2.2 Policy fetched but could not be parsed Wrong Content-Type, malformed key/value pairs, max_age out of range Fetch policy body and inspect with curl -sS https://mta-sts.DOMAIN/.well-known/mta-sts.txt
sts-webpki-invalid §4.3.2.2 Web PKI validation failed for the policy host Expired or untrusted cert on mta-sts subdomain openssl s_client -connect mta-sts.DOMAIN:443 -servername mta-sts.DOMAIN
certificate-host-mismatch §4.3.1 MX server cert SANs do not include the MX hostname Shared hosting cert, or MX hostname differs from cert CN/SANs openssl s_client -starttls smtp -connect MX_HOST:25 -servername MX_HOST + inspect SANs
certificate-expired §4.3.1 MX server cert is past its expiry Missed renewal on mail server cert Same openssl command, check notAfter date
certificate-not-trusted §4.3.1 MX server cert chain not trusted by sender Self-signed cert, missing intermediate Same openssl command, inspect issuer chain
starttls-not-supported §4.3.1 MX server did not advertise STARTTLS STARTTLS disabled or not installed on mail server openssl s_client -starttls smtp -connect MX_HOST:25, look for STARTTLS in EHLO response
validation-failure §4.3.1 STARTTLS negotiation failed for another reason TLS handshake error; sender SHOULD include failure-reason-code in the report Check failure-reason-code field in TLS-RPT JSON for sender-specific detail

Raw TLS-RPT is JSON, and reading it by hand gets tedious fast. Receiver Shield parses it automatically, grouping failures by type, sender, and MX host with trends over time. No manual .json.gz decompression required.

Our TLS-RPT report failures guide covers every failure type with diagnosis commands.

7. Improper MTA-STS removal

When you want to disable MTA-STS, deleting the DNS records and policy file feels natural. It is also the risky path.

Senders that previously fetched your enforce-mode policy have it cached. If the policy file disappears, those senders continue enforcing the cached version until max_age expires. If your MX hostnames or certificates change during that window, the cached policy no longer matches, and email bounces.

The correct procedure:

  1. Change the policy mode to none in the policy file
  2. Update the id in the _mta-sts DNS TXT record so senders re-fetch
  3. Keep the policy file accessible for at least max_age seconds
  4. Only then remove the DNS records

This is the MTA-STS equivalent of DMARC’s “do not jump from p=reject to removing the record.” Receiver Shield serves mode: none during safe teardown and rollback so senders can fetch the removal policy before records disappear.

Our enforce mode and rollback guide explains the full teardown sequence.

What tools check MTA-STS and TLS-RPT alongside DMARC and SPF?

Most checkers test one protocol at a time. The free domain checker at /domains runs DMARC, SPF, DKIM, MTA-STS, and TLS-RPT together. Paste your domain and you get a status for every layer at once, so you can see, for example, that MTA-STS is misconfigured while DMARC is already at p=reject.

The pattern behind these failures

Most of these issues have the same root cause: DNS, HTTPS policy hosting, and mail server TLS all have to agree, and MTA-STS does not give you immediate feedback when they drift. You make a change, and if something is wrong, you may only find out when a sender’s cache expires or when TLS-RPT reports arrive.

That feedback delay is what makes MTA-STS harder to operate than DMARC. With DMARC, aggregate reports often start arriving within a day once receivers send traffic. With MTA-STS, you publish records, host a policy file, configure TLS on your MX servers, wait for senders to fetch the policy, wait for TLS-RPT reports to accumulate, and then parse the JSON to see what happened.

Receiver Shield shortens that loop. It hosts the policy, parses TLS-RPT, and shows what would break before you enforce. A hosted deployment uses these records:

mta-sts.example.com. CNAME mta-sts-proxy.dmarctrust.com.
_mta-sts.example.com. TXT "v=STSv1; id=<generated_policy_id>;"
_smtp._tls.example.com. TXT "v=TLSRPTv1; rua=mailto:<generated DMARCTrust reporting address>"

DMARCTrust serves the policy at /.well-known/mta-sts.txt, generates the policy ID from the policy content, parses incoming TLS-RPT reports, and serves mode: none during safe teardown or rollback. New to MTA-STS? Start with the MTA-STS guide and run your domain through the free domain checker to see where you stand.

Read Next

View all posts
From p=none to p=reject: how to enable DMARC enforcement in 2026
dmarc-setup ·

From p=none to p=reject: how to enable DMARC enforcement in 2026

Forums show the same anxiety pattern: 'I want p=reject, but I'm afraid I'll block legit mail.' The rollout is mostly about gates: inventory done, alignment fixed, SPF lookup limit avoided, and then staged enforcement.

DT
DMARCTrust
8 min read
VMC vs CMC certificates: BIMI cost and requirements (2026)
email-deliverability ·

VMC vs CMC certificates: BIMI cost and requirements (2026)

A practical buyer's guide to VMC and CMC certificates for BIMI in 2026. Covers trademark vs prior-use paths, current prices, authorized issuers, and the Gmail checkmark distinction.

DT
DMARCTrust
8 min read
Who is sending mail as us? The Shadow IT sender inventory problem
dmarc-monitoring ·

Who is sending mail as us? The Shadow IT sender inventory problem

The biggest practical blocker to moving beyond p=none isn't DNS syntax. It's discovering every legitimate sender. DMARC reports expose these "unknown senders" and Shadow IT that you didn't even know existed.

DT
DMARCTrust
4 min read

Need expert help with email deliverability?

Hire an email deliverability consultant who has shipped billions of emails. Free assessment, hands-on engagement, written quote before any work starts.