The single most important decision in an MTA-STS deployment is not whether to publish a policy — it is which mode to publish it in, and when to change it. The mode is one line in your policy file, but it is the line that decides whether a sending server refuses to deliver mail to you when TLS cannot be verified. Get the sequencing right and MTA-STS is invisible to everyone; get it wrong and you can silently lose inbound mail from senders who were doing everything correctly. This guide walks through the three modes, what a remote sender actually does in each, and how to use TLS-RPT as the evidence that tells you it is safe to enforce.
The three modes, and what a sender does with each
An MTA-STS policy is a small text file served at https://mta-sts.yourdomain/.well-known/mta-sts.txt. It always begins with version: STSv1 and carries a mode: line whose value is one of none, testing or enforce, followed by one or more mx: lines and a max_age: in seconds.
In enforce, a compliant sending MTA that has fetched and cached your policy will refuse to deliver a message if it cannot open an authenticated TLS session to one of the listed MX hosts. "Authenticated" means STARTTLS succeeds, the certificate is valid and unexpired, chains to a public root, and the certificate identity matches the MX hostname in the policy. If any of that fails, the sender does not fall back to plaintext — it defers the message and retries, and eventually bounces it. That is the whole point: it removes the downgrade path an attacker could otherwise exploit.
In testing, a sender evaluates your policy exactly as it would in enforce — it checks TLS, matches the MX list, validates the certificate — but it does not act on a failure. Delivery proceeds as normal, and instead the sender emits a TLS-RPT report describing what it saw. Testing gives you the enforcement verdict without the enforcement consequences.
mode: none is a tombstone. It tells senders you no longer have an active policy, so they should stop applying a previously cached one. You use it to retire MTA-STS cleanly, not as a starting point.
Why you always start in testing
The risk in MTA-STS is not that your mail server lacks TLS — most do. The risk is a mismatch between what your policy claims and what is actually deployed. The classic failures are an mx: list that omits one of your real MX hosts, a certificate on an MX that has expired or does not include the MX hostname as a subject alternative name, or a secondary/backup MX run by a third party that quietly stopped supporting valid TLS. None of these are visible from your own outbound mail. Testing mode surfaces them from the perspective of the senders who matter — the large providers who honour MTA-STS and who send you real mail every day.
Because policies are cached by senders for up to max_age seconds, it is also sensible to keep max_age modest during testing (for example a few days) so that corrections propagate quickly, then raise it once you are in enforce and stable. A long max_age such as 604800 (one week) or more is appropriate for a settled enforce policy, because it lengthens the window in which a network attacker cannot trick a sender into ignoring the policy.
Reading TLS-RPT before you flip the switch
Testing mode is only useful if you are collecting the reports it generates. That requires a TLS-RPT record: a TXT record at _smtp._tls.yourdomain containing v=TLSRPTv1; rua=mailto:tlsreports@yourdomain. Reporting senders will then send you a daily JSON aggregate summarising every delivery attempt, grouped by policy type and result.
What you are looking for is simple: are there any failure result types against your domain? Success rows (result-type of successful-session, or a policy that applied with no failures) mean that sender validated TLS against your MX and would have delivered under enforce. Failure rows are the ones to investigate — starttls-not-supported, certificate-expired, certificate-host-mismatch, or validation-failure each point at a concrete misconfiguration. For a fuller breakdown of the report format and each result type, see what TLS-RPT tells you.
Give it time. A day or two of reports only reflects the senders who happened to mail you in that window. Two to four weeks is a reasonable observation period for a domain with steady inbound volume, because it captures the long tail of less frequent correspondents and any certificate renewal events that occur mid-period. When you have a run of reports with no failure types attributable to your own configuration, you have earned the confidence to enforce.
Flipping to enforce
The change itself is trivial: edit the policy file so mode: reads enforce, then bump the id in your _mta-sts TXT record so senders re-fetch it. The id in DNS is what signals a policy change — if you edit the file but leave the id unchanged, senders will keep serving the cached testing policy until it expires. Any random-ish, monotonically increasing string works; a date-and-counter such as 20260706000001 is a common convention.
Do not raise max_age and switch to enforce in the same change if you can avoid it. Flip to enforce first, watch another cycle of TLS-RPT to confirm nothing regressed, and then lengthen max_age. It keeps each change independently reversible.
Your rollback plan
If enforce causes a problem — a certificate you did not know about lapses, or you add an MX you forgot to list — you have two levers. The immediate one is to edit the policy back to mode: testing and bump the id; that stops any deferrals as soon as senders re-fetch. The important caveat is caching: senders may hold the enforcing policy for up to the max_age you set, so a shorter max_age during and just after rollout is itself part of your rollback plan. This is exactly why you do not jump to a week-long max_age on day one.
The nuclear option is mode: none plus an id bump, which tells senders to abandon the policy entirely. Reserve it for a genuine retirement or a serious outage. For a wobble during rollout, dropping back to testing is the proportionate move because it preserves the reporting you still want.
The sequence in one line
Publish TLS-RPT, then publish an MTA-STS policy in testing with a short max_age, watch the reports for two to four weeks, fix anything they flag, switch mode to enforce and bump the id, confirm with another cycle of reports, then extend max_age. It is deliberately unhurried, and that is what makes it safe. If you also want to verify the underlying STARTTLS behaviour of your MX hosts directly, STARTTLS Studio tests the TLS handshake, and DKIM Studio covers the authentication side of the same messages.