egressif.

Resources / Transport Security

MTA-STS (RFC 8461): policy, records, and modes

MTA-STS lets a domain demand authenticated TLS for inbound mail using DNS plus an HTTPS-served policy, without DNSSEC. This page covers the _mta-sts TXT record, the well-known policy file, the three modes, max_age caching, and exactly how a sending MTA validates and applies a policy - all per RFC 8461.

Last checked: June 22, 2026

MTA-STS (SMTP MTA Strict Transport Security, RFC 8461, September 2018) is a mechanism that lets a receiving domain “declare their ability to receive Transport Layer Security (TLS) secure SMTP connections and to specify whether sending SMTP servers should refuse to deliver to MX hosts that do not offer TLS with a trusted server certificate.” In plain terms: it turns the opportunistic, strippable TLS of plain STARTTLS into an enforced, certificate-validated requirement - and it does so without needing DNSSEC.

The 60-second version

  • Two pieces: a DNS TXT record at _mta-sts.<domain> that signals a policy exists and carries a version id, and the policy file itself served over HTTPS at https://mta-sts.<domain>/.well-known/mta-sts.txt.
  • The policy lists allowed mx hostnames, a mode, and a max_age (cache lifetime in seconds).
  • Three modes: enforce (refuse delivery on TLS/cert/MX failure), testing (deliver anyway, but report the failure via TLS-RPT), none (no policy; used to opt out cleanly).
  • Trust is the Web PKI: the MX certificate must chain to a publicly trusted CA, be unexpired, and match the hostname. No DNSSEC required.
  • Senders cache the policy for up to max_age and key off the TXT id to notice updates without re-fetching the file.
RECEIVER PUBLISHES_mta-sts TXTv=STSv1id=20260601T…HTTPS POLICY.well-known/mta-sts.txtmode: enforcemx, max_ageSENDER FETCHcheck TXT idGET policyCACHEmax_ageweeksENFORCE TLSnext send
The receiver publishes a TXT signal plus an HTTPS policy; the sender fetches, caches it for max_age, and enforces validated TLS.

The two records, side by side

; 1. The signal: a TXT record at _mta-sts.<domain>
_mta-sts.example.com.   IN TXT "v=STSv1; id=20260601T120000Z;"
# 2. The policy: served at
#    https://mta-sts.example.com/.well-known/mta-sts.txt
#    Content-Type: text/plain
version: STSv1
mode: enforce
mx: mx1.example.com
mx: mx2.example.com
mx: *.mail-backup.example.com
max_age: 1296000

The _mta-sts TXT record

The record lives at the label _mta-sts under the Policy Domain - for example.com, that is _mta-sts.example.com. It is “US-ASCII, semicolon-separated key/value pairs” with two defined fields:

FieldRequiredValue
vYesCurrently only STSv1
idYes1 to 32 letters/digits, uniquely identifying this policy instance

The id is the clever part. Senders compare the id they see against the id of the policy they have cached; if it matches, the cached policy is still current and no HTTPS fetch is needed. There is no ordering implied between id values - any change is just “different.”

RFC 8461 is strict about parsing: if more than one _mta-sts TXT record is returned, records that do not begin with v=STSv1; are discarded, and “if the number of resulting records is not one, or if the resulting record is syntactically invalid, senders MUST assume the recipient domain does not have an available MTA-STS Policy.” The record MAY be a CNAME (followed by senders) to support delegation.

The HTTPS policy file

The policy is fetched with an HTTPS GET from a fixed location. The Policy Host name is built by prepending mta-sts to the Policy Domain, so for example.com the URL is exactly:

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

The body is CRLF-separated key/value pairs (senders SHOULD check the media type is text/plain):

KeyMeaning
versionOnly STSv1
modeOne of enforce, testing, none
max_ageCache lifetime in seconds, non-negative integer, maximum 31557600
mxAn allowed MX host pattern; repeat the key, one per line, for multiple MXes

The mx patterns must match the actual MX hostnames. A wildcard is allowed but constrained: the * “may only be used to match the entire left-most label.” So *.example.com matches mail.example.com but not example.com and not foo.bar.example.com. RFC 8461’s own security section warns that a loose pattern like *.example.com means any holder of a valid hostname and CA-signed certificate in that space (say dhcp-123.example.com) becomes a valid MX from the policy’s point of view - so keep the list tight.

The three modes

The mode field decides what a sender does when a candidate MX fails validation (wrong MX name, bad/expired/untrusted certificate, or no STARTTLS):

ModeSender behaviour on failure (RFC 8461)
enforce”Sending MTAs MUST NOT deliver the message to hosts that fail MX matching or certificate validation or that do not support STARTTLS.” Failure is treated as a transient error and retried; mail is delayed, never sent in the clear.
testingThe message “may be delivered as though there were no MTA-STS validation failure”; if the sender also implements TLS-RPT, it sends a report of the failure. This is your safe rollout mode.
noneThe sender treats the domain “as though it does not have any active policy.” Used to opt out before removing the records entirely.

A subtle but important enforce rule: when delivery fails under an enforcing policy, a compliant MTA “MUST NOT permanently fail to deliver messages before checking, via DNS, for the presence of an updated policy.” In all cases such failures SHOULD be treated as transient and retried, so you can fix a misconfiguration on the fly without bouncing mail.

Certificate validation

For a candidate MX to pass, two things must hold (RFC 8461 §4):

  1. MX match. At least one mx pattern in the policy matches the selected MX hostname.
  2. Certificate validity. During STARTTLS the MX presents an X.509 certificate that is not expired, chains “to a root CA that is trusted by the Sending MTA,” and carries a subject alternative name (SAN) DNS-ID matching the hostname. The expected trust set is “similar to those in widely deployed web browsers and operating systems.”

The HTTPS policy fetch itself is also authenticated: the Policy Host must present a certificate valid for the mta-sts host (for example mta-sts.example.com), chaining to a trusted CA. And the fetch is deliberately rigid - “HTTP 3xx redirects MUST NOT be followed, and HTTP caching … MUST NOT be used,” and only an HTTP 200 response is a valid policy.

Operational guard rails from RFC 8461: a suggested HTTPS timeout of one minute, a suggested maximum policy size of 64 kilobytes, and on a failed fetch, rate-limiting further attempts “to a period of five minutes or longer per version ID.” SMTP clients MUST support SNI (sending the MX hostname for SMTP, the Policy Host for the HTTPS fetch) and MUST support TLS 1.2 or TLS 1.3 or higher.

Caching and the application flow

MTA-STS leans hard on caching, both for performance and for security. A sender caches a fetched policy for up to its max_age and, per RFC 8461’s control flow:

  1. Check for a cached policy whose age has not exceeded its max_age; if none, fetch a fresh one (often asynchronously, so delivery is not blocked).
  2. For each candidate MX in priority order, attempt delivery; in enforce mode, verify STARTTLS support and certificate/host validity. If a candidate fails, move to the next.
  3. A delivery attempt “MUST NOT be permanently failed until the sender has first checked for the presence of a new policy” via the TXT id.

Two caching rules protect against attacks on policy discovery:

  • If no live policy can be fetched but a valid (non-expired) cached policy exists, the sender “MUST apply that cached policy.”
  • The mere absence of a TXT record “is not by itself sufficient to remove a sender’s previously cached policy.”

Because the initial fetch (and each refresh) is the vulnerable moment, RFC 8461 recommends max_age values “as long as is practical” - “typically … in the range of weeks or greater” - and proactive refresh (a suggested once per day) rather than waiting for expiry. It also recommends alerting administrators on repeated refresh failures, “unless the cached policy mode is ‘none’.” This trust-on-first-use exposure is the structural difference from DANE, which can prove record absence via DNSSEC.

Updating a policy safely

A policy lives in two places, so order matters. To change it:

  1. Update the HTTPS policy body first. Per RFC 8461, this “ordering avoids the risk that senders, seeing a new TXT record, mistakenly cache the old policy from HTTPS.”
  2. Then publish a new TXT id to trigger re-fetching.

Remember that senders may keep using a cached policy until both endpoints are updated and the TXT record’s TTL has passed, so keep old MX hosts working during the transition or risk delays.

Removing MTA-STS

You do not just delete the records. The clean opt-out (RFC 8461 §8.3) is:

  1. Publish a policy with mode: none and a small max_age (for example one day).
  2. Publish a new TXT id so senders fetch it.
  3. Once all previously served policies have expired, remove the TXT record and the HTTPS endpoint.

The none mode exists precisely so senders can tell an intentional opt-out apart from an attack.

Delegating to a provider

Domains that outsource mail hosting can delegate the whole mechanism. Point the _mta-sts TXT record at the provider via CNAME so the provider controls update signaling:

_mta-sts.user.example.   IN CNAME _mta-sts.provider.example.

Then point the mta-sts policy host at the provider (via address/CNAME with a suitable certificate, or a reverse proxy). One caveat from RFC 8461: the policy endpoint must still present a certificate valid for the customer’s Policy Host (mta-sts.user.example), not the provider’s.

MTA-STS vs DANE in one line

Both enforce authenticated TLS and resist downgrades. MTA-STS uses the Web PKI and HTTPS and needs no DNSSEC, “at a cost of risking malicious downgrades” on first contact; DANE uses DNSSEC and can prove a record is absent, but requires a DNSSEC-signed zone. They coexist, and a failing DANE result must never be overridden by MTA-STS. The DANE page has the full comparison table.

Common confusion

  • “The TXT record is the policy.” No. The TXT record only signals that a policy exists and carries the id. The enforceable content - modes, MX list, max_age - lives in the HTTPS file.
  • testing mode encrypts mail.” testing changes nothing about delivery; it only generates TLS-RPT reports. Encryption still depends on the MX offering STARTTLS. Use testing to gather data, then move to enforce.
  • “A short max_age is safer.” The opposite. A short max_age widens the window in which an attacker who blocks discovery can downgrade you. Weeks or longer is the recommendation.
  • “MTA-STS needs DNSSEC.” It does not - that is its whole reason to exist alongside DANE. It needs a valid HTTPS certificate on the mta-sts host instead.

What this means for you, and what Egressif does

On the domains we operate, we publish a complete MTA-STS policy and keep its mx list exactly matched to the live MX hosts, with a max_age measured in weeks so the policy resists first-contact downgrades. We pair every MTA-STS deployment with TLS-RPT and start in testing so we can confirm from real sender reports that TLS negotiates cleanly before we move to enforce. When MX hosts or certificates change, we update the HTTPS policy before bumping the TXT id, in the order the RFC prescribes, so no sender caches a stale policy. We do not pretend MTA-STS authenticates anything DNSSEC could not do better - where a domain is signed we also run DANE - but for the large share of senders who honor MTA-STS and not DANE, it is the difference between encrypted-if-convenient and encrypted-and-verified.

Tell us what you run today.

Domains, rough volume, current providers, and what hurts. You will get a straight answer on fit, and a real number, in one conversation.

Talk to our team