Email transport · MTA-STS

MTA-STS stuck in testing mode: how to move to enforce safely

The short answer

In mode: testing, sending servers check your mail servers' TLS but deliver anyway when the check fails; they only report it (RFC 8461 §5). To enforce: read TLS-RPT reports until they are clean, make sure every MX is in the policy and serves a valid certificate for its own name, change the mode, and change the id in your _mta-sts record.

What a sender does, mode by mode

The policy file decides what a sending server does when it cannot set up a secure connection to one of your MX hosts:

ModeValid certificate, MX in the policyCheck fails
noneDelivers as if there were no policyDelivers
testingDelivers over TLSDelivers anyway and reports the failure
enforceDelivers over TLSDoes not deliver to that host; tries another listed MX, or queues and retries

Senders keep your policy for max_age seconds and fetch it again only when the id in your _mta-sts TXT record changes. Change the file without changing the id, and senders that have it cached go on applying the old mode until max_age runs out.

What testing leaves open, and what enforce can break

  • Testing protects nothing. Someone who strips STARTTLS or answers with a false certificate still receives the mail: in testing mode the sender delivers anyway. RFC 8461 §5
  • An MX missing from the policy stops receiving mail under enforce. Senders deliver only to hosts that match an mx: line. RFC 8461 §4.1
  • A certificate that does not name the MX host fails. Enforce needs a valid, unexpired certificate from a public CA that matches the MX hostname itself. RFC 8461 §4.1
  • The policy file must be served exactly. HTTPS on mta-sts.<your domain>, at /.well-known/mta-sts.txt, with a valid certificate, as text/plain and with no redirect. A sender that cannot fetch it keeps its cached copy until that expires. RFC 8461 §3.3

Check your MTA-STS policy

The free domain check reads your _mta-sts record and policy file, and tells you the mode, the max_age, whether the file could be fetched and which MX hosts the policy leaves out.

Free, no account. We read only public DNS and what your servers show to anyone who connects.

Fix it, step by step

  1. Publish TLS-RPT first

    Add a TXT record at _smtp._tls.example.com with v=TLSRPTv1; rua=mailto:tls-reports@example.com. Senders then send you a daily report of TLS successes and failures (RFC 8460).

  2. Read the reports until they are clean

    Look for failures by MX host. A run of clean reports across a normal period of mail traffic, often a couple of weeks, is the signal that enforce is safe.

  3. Match every MX to the policy

    Each MX host must match an mx: line in the policy file. A pattern such as *.mail.example.com covers one label only.

  4. Check every MX certificate

    Each MX must present a valid, unexpired certificate from a public CA, with its own hostname in it. An internal or self-signed certificate fails under enforce.

  5. Switch to enforce and raise max_age

    Change the file to mode: enforce and set max_age to at least a week (604800 seconds).

  6. Change the id

    Change the id value in the _mta-sts TXT record, for example to today's date and time. That is what tells senders to fetch the new policy.

  7. Before adding an MX later, update the policy first

    Add the new host's mx: line, change the id, wait for max_age, and only then point mail at the new host.

Common mistakes

Changing the file but not the id

Senders that cached the testing policy keep applying it until max_age runs out, which can be weeks.

In SkyQon's result: we fetch the policy file itself, so our result can show enforce before senders do. The id is what makes them fetch it.

Adding a new MX before updating the policy

Under enforce, senders refuse to deliver to a host that matches no mx: line.

In SkyQon's result: a finding names every MX host that matches no mx: line. In enforce mode it says senders will refuse or skip those hosts; in testing mode, that nothing is refused yet.

Serving the policy behind a redirect

Many web servers redirect by default. RFC 8461 forbids following a redirect for the policy file, so senders treat MTA-STS as missing.

In SkyQon's result: a finding that the policy could not be fetched, with the reason, such as a redirect or a content type other than text/plain.

A max_age of minutes

Senders then fetch the policy all the time, and on a bad day they fall back to no policy sooner.

In SkyQon's result: a finding when max_age is under one day.

What SkyQon does and does not do

What it finds

Your _mta-sts record and policy file: the mode, max_age, whether each MX host matches an mx: line, whether the file can be fetched, and whether a TLS-RPT address is published.

What you get

In the free check, a finding for testing mode and for MX hosts the policy leaves out. On a monitored domain, an alert while the policy stays in testing or leaves out an MX host. On Pro and up, the TLS-RPT reports that senders send you, read and summarised.

What it is not

We do not yet judge each MX certificate for MTA-STS, and we do not edit your policy file. Check the MX certificates before you enforce.

MTA-STS: questions people ask

How long should I stay in testing mode?
Until your TLS-RPT reports are clean across a normal period of mail traffic, often a couple of weeks. RFC 8461 sets no fixed period.
Do I need TLS-RPT for MTA-STS to work?
No, but without it you cannot see failures while you are in testing, so you have no way of knowing when enforce is safe.
What happens to mail if an MX certificate expires under enforce?
Senders do not deliver to that host. They try another MX that passes, or keep the message queued and retry. Most mail servers retry for several days before they bounce a message.
Does MTA-STS protect the mail I send?
No. It tells other servers how to deliver mail to you. Mail you send is protected by the receiving domain's own policy.
Is MTA-STS the same as DANE?
No. DANE publishes certificate details in DNS and needs DNSSEC; MTA-STS uses an HTTPS policy and public CA certificates. A domain can publish both, and MTA-STS never overrides a failing DANE check. SkyQon checks DANE on your inbound mail too.
What max_age should I use?
RFC 8461 allows up to 31557600 seconds, about a year. A week (604800) or more is common under enforce; shorter while testing, so a change reaches senders sooner.
What does mode: none do?
It withdraws the policy. Use it when you retire MTA-STS: publish mode: none, change the id, and remove the records only after max_age has passed.
Why does the id matter so much?
Senders cache the policy and look at the TXT record's id to decide whether to fetch it again. The id is the only signal they have that something changed.

Know when it is safe to enforce.

The free check shows your MTA-STS mode today. On Pro and up, SkyQon reads your TLS-RPT reports, so you see the failures before you switch.