Blog
SavedSearch
Visit Hostlelo

Set Up MTA-STS and TLS-RPT to Force Encrypted Inbound Email

Add TLS-RPT reports, publish an MTA-STS policy in testing mode, then enforce safely so other servers must use encrypted TLS to deliver your email.

The short answer

MTA-STS (RFC 8461) tells other mail servers to deliver to your domain only over TLS 1.2 or higher, to the MX hosts you list, with a valid public certificate. You publish a policy file at `https://mta-sts.yourdomain/.well-known/mta-sts.txt` and a TXT record at `_mta-sts.yourdomain`, and add a TLS-RPT (RFC 8460) record at `_smtp._tls.yourdomain` to receive daily reports. Start in testing mode for about two weeks, then update the file to enforce before changing the TXT id.

Reading options

On this page

MTA-STS is a small policy file plus one DNS record that tells other mail servers: "only deliver to my domain over encrypted TLS, to these mail servers, with a valid certificate." TLS-RPT is a second DNS record that asks those servers to send you a daily report when they could not connect securely. Together they close a gap that has existed in server-to-server email for a long time.

Here is the surprising part. The encryption most mail servers use today is opportunistic, and RFC 8461 (published September 2018) says plainly that "any attacker who can delete parts of the SMTP session (such as the "250 STARTTLS" response)" can "perform downgrade or interception attacks." In other words, someone in the middle can quietly remove the offer to encrypt, and the mail may travel in plain text.

By the end of this guide you will have TLS-RPT reports arriving, an MTA-STS policy running in safe testing mode, and a clear plan for switching to enforce without bouncing real mail.

Heads up: a wrong enforce policy can make legitimate inbound mail bounce. Cloudflare's documentation warns that a misconfigured enforce policy causes legitimate inbound mail to be rejected. Everything in this guide starts in mode: testing, with TLS-RPT reports switched on first, so you can see problems before they cost you a single email.

What MTA-STS and TLS-RPT actually are

A few words first, in plain terms. TLS (Transport Layer Security) is the encryption that protects a connection between two computers. A certificate authority is a trusted company that issues the digital certificates servers use to prove who they are. An MX record (mail exchanger) is the DNS entry that says which servers receive email for your domain. A TXT record is a DNS entry that simply holds a piece of text that other systems can read.

Think of it like a courier delivering a parcel to your office. Today the courier asks "do you have a locked mailbox?" and if nobody answers, they leave the parcel on the doorstep. MTA-STS is a sign at the gate that says: "We always have a locked mailbox, here are the only two mailbox addresses we use, and if you cannot use one of them, do not leave the parcel."

The RFC describes MTA-STS as a way for mail providers "to 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." TLS reporting is defined separately in RFC 8460.

Google's Workspace documentation sums up the effect: with MTA-STS on, external servers should send mail to your domain only if the connection is "Authenticated with a valid public certificate" and "Encrypted with TLS 1.2 or higher."

MTA-STS has three moving parts:

  • A TLS-RPT TXT record at _smtp._tls.example.com that says where to send reports.
  • A policy file at https://mta-sts.example.com/.well-known/mta-sts.txt that lists your mail servers and the mode.
  • A discovery TXT record at _mta-sts.example.com that tells senders a policy exists and carries a version id.

Why this matters: SPF, DKIM and DMARC protect against people faking your domain on mail they send. MTA-STS protects mail that other people send to you while it is travelling. If you have not set up the first group yet, start with this SPF, DKIM and DMARC guide, then come back.

Before you start

Plan for about an hour of hands-on work spread over a few weeks of watching. The risk is low while you stay in testing mode.

  • Access to the DNS for your domain. Google says to add the records "at your domain host, not in your Google Admin console", and the same idea applies whoever runs your email.
  • A backup of your current DNS zone. Use your DNS host's export or backup option and save the file somewhere safe before you add anything.
  • A way to publish a small text file over HTTPS on the subdomain mta-sts.example.com, with a certificate from a trusted public certificate authority.
  • A mailbox to receive reports, for example tlsrpt@example.com. Reports are JSON files, so a dedicated mailbox keeps them out of your way.
  • A terminal with dig and curl for the checks. Any Linux or macOS machine has them.
  • Your real list of MX hosts. You will confirm these in Step 1, so do not guess them.

Quick tip: your mail servers themselves must support TLS 1.2 or higher with a valid certificate. The RFC says MTAs supporting MTA-STS "MUST have support for TLS 1.2 RFC5246] or TLS 1.3 [RFC8446] or higher." If you run your own mail server, [check its TLS version first. If a big provider runs your mail, they handle that part.

Set it up step by step

The order below follows the UK government's published sequence on security.gov.uk: reports first, then the policy file in testing mode, then the discovery record, then enforce. Google also recommends adding the TLS reporting record before the MTA-STS record.

Step 1: Back up your zone and confirm your real MX records

Export your zone with your DNS host's export or backup option, and keep the file.

Now look up the MX records that the world actually sees. This command asks public DNS for your domain's mail servers in short form.

dig MX example.com +short

You should see one line per mail server, each with a priority number and a host name ending in a dot. The values below are made-up examples.

10 mx1.example.net.
20 mx2.example.net.

Write down every host name exactly, without the trailing dot. Each one needs its own mx line in your policy. Google's policy guide says "The policy must have an mx entry for each MX record added to the domain."

Heads up: if you are part way through moving email to a new provider, wait until the move is finished. A policy that lists the old servers, or misses the new ones, is the classic way to bounce mail once you enforce.

Step 2: Add the TLS-RPT record so reports start flowing

TLS-RPT costs nothing to turn on and it is the safety net for everything else. Sending servers that support it will email you a daily summary of successful and failed secure connections. RFC 8460 says a report "SHOULD cover a full day, from 00:00-24:00 UTC", and reports are JSON, usually gzip compressed.

In your DNS host, go to your domain's DNS records area and add a new TXT record with these values.

Type:  TXT
Name:  _smtp._tls.example.com
Value: v=TLSRPTv1; rua=mailto:tlsrpt@example.com

Some DNS panels want only _smtp._tls in the name field and add your domain for you.

If you want reports in more than one mailbox, Google's documentation says to separate the addresses with commas. This value sends reports to two addresses.

v=TLSRPTv1; rua=mailto:tlsrpt@example.com,mailto:security@example.com

Google says DNS changes can take up to 24 hours to take effect, depending on the record's TTL (time to live, the number of seconds resolvers may keep an old answer).

Step 3: Write the policy file in testing mode

The policy is a plain text file named mta-sts.txt. RFC 8461 defines the fields:

  • version: must be STSv1.
  • mode: one of enforce, testing or none.
  • mx: one line for each allowed mail server host name.
  • max_age: how long, in seconds, senders may cache the policy, with a maximum value of 31557600.

In testing mode, senders still deliver mail when something fails and send you a report. The RFC says that in this case "messages may be delivered as though there were no MTA-STS validation failure." That is why testing is safe.

For max_age, the UK guidance uses 86401 seconds (24 hours and one second) for testing and 1209600 seconds (2 weeks) for enforce. Google's example uses 604800, which is 7 days. A short value while testing means mistakes do not stay cached for long.

The RFC describes the file as "CRLF-separated key/value pairs", meaning Windows style line endings. This command writes the file with CRLF endings so you do not have to think about your text editor. Replace the made-up mx hosts with the ones you wrote down in Step 1.

printf 'version: STSv1\r\nmode: testing\r\nmx: mx1.example.net\r\nmx: mx2.example.net\r\nmax_age: 86401\r\n' > mta-sts.txt

The finished file reads like this.

version: STSv1
mode: testing
mx: mx1.example.net
mx: mx2.example.net
max_age: 86401

About wildcards: the RFC allows * only as the whole leftmost label. So *.example.net matches mx1.example.net but not example.net or a.b.example.net. The UK guidance goes further and says not to use wildcard MX values at all. When you can, list each host by its full name.

Step 4: Publish the file on the mta-sts subdomain

The file must live at exactly this address. The RFC builds the host name by "prepending "mta-sts" to the Policy Domain" and fetches the file from the .well-known/mta-sts.txt path.

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

Google lists the hosting rules: the subdomain must start with mta-sts, the server must support HTTPS, the certificate must be "signed and trusted by a third-party root certificate authority", and the file goes inside a directory named .well-known.

On ordinary web hosting, that usually means a few jobs:

  1. Create the subdomain mta-sts.example.com with your hosting panel's subdomain tool, and point it at your web server with an A record or a CNAME (an alias that points one name at another name). If you are unsure which to use, see CNAME or A record.
  2. Issue a free certificate for mta-sts.example.com in your panel. Check your host's documentation for the exact menu, because it differs between panels.
  3. Upload mta-sts.txt into a folder named .well-known in that subdomain's document root.

These rules from RFC 8461 trip people up here:

  • The response must be HTTP 200. The RFC says policies "are only valid if the HTTP response code is 200 (OK)."
  • Redirects are not followed. If your site forces a redirect from mta-sts.example.com to www.example.com, the policy fails.
  • Senders should check the media type is text/plain.

Quick tip: a certificate that expires on the mta-sts subdomain breaks the policy too, so make sure it renews on its own. This guide on testing SSL auto-renewal shows how to check.

Step 5: Check the file is visible, then wait 48 hours

Before telling the world the policy exists, make sure it loads. This command fetches only the response headers.

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

You want to see 200 on the first line and a Content-Type that starts with text/plain. Any 301 or 302 means a redirect, and you need to remove it for this subdomain.

The UK guidance says to leave 48 hours after confirming the file is visible before you add the discovery record. That gives DNS and certificates time to settle everywhere.

Step 6: Add the MTA-STS discovery record

This TXT record is the switch that tells senders to go and fetch your policy. Add it in the same DNS records area as before.

Type:  TXT
Name:  _mta-sts.example.com
Value: v=STSv1; id=20261109120000

The id must be 1 to 32 letters or digits, and it must change every time the policy changes. Google suggests using the current date and time, which is what the example above does. Senders compare the id to decide whether to download your policy again.

Step 7: Read the reports for at least two weeks

Now you wait and read. The UK guidance says to monitor for at least 2 weeks, with no TLS-RPT failures, before you enforce. Google also recommends starting with testing mode for 2 weeks.

Each report is a JSON file with counts of successful and failed sessions. Look for any failure count above zero, and for trouble clustered on one MX host.

Made-up example: Priya runs a small accounting firm on example.com. Her first week of reports shows thousands of successful sessions and a handful of failures, all against mx2.example.net, with a certificate error. She asks her mail provider, who finds the backup server was using an expired certificate. In testing mode, every one of those messages still arrived. Had she enforced on day one, they would have bounced.

Step 8: Switch to enforce, in the right order

When the reports are clean, change the policy file first and the DNS record second. The RFC says recipients "SHOULD also update the HTTPS policy body before updating the TXT record." Google confirms that moving from testing to enforce needs both a file update and a new policy ID in DNS.

This command rewrites the file in enforce mode with the UK example value of 1209600 seconds (2 weeks).

printf 'version: STSv1\r\nmode: enforce\r\nmx: mx1.example.net\r\nmx: mx2.example.net\r\nmax_age: 1209600\r\n' > mta-sts.txt

Upload it to the same .well-known folder, run the curl check again, and only then change the TXT record to a new id.

Type:  TXT
Name:  _mta-sts.example.com
Value: v=STSv1; id=20261124090000

Keep the TLS-RPT record in place forever. It is how you will hear about a problem after you enforce.

Variant: Cloudflare Email Service

If your domain uses Cloudflare Email Service, Cloudflare documents a shortcut where it serves the policy for you. At the time of writing (9 November 2026), the steps on Cloudflare's MTA-STS page are these. This page covers Email Service. I did not check whether it also applies to Cloudflare Email Routing, so confirm with Cloudflare if that is what you use (for Email Routing basics, see this aliases and SPF guide).

  1. In the Cloudflare dashboard, open the Records page for your domain.
  2. Create a CNAME record named _mta-sts pointing to _mta-sts.mx.cloudflare.net, with the proxy turned off (DNS only).
  3. Deploy the MTA-STS proxy Worker from the cloudflare/docs-examples repository, path workers/mta-sts-proxy, using the Deploy to Cloudflare button on that page.
  4. In the Worker, go to Settings > Domains & Routes > + Add and enter mta-sts.example.com.

With this route, the CNAME replaces the discovery TXT record from Step 6, because Cloudflare's own name carries the TXT value. You still add your own TLS-RPT record from Step 2.

Heads up: Cloudflare's example policy is already in mode: enforce, with mx: *.mx.cloudflare.net and max_age: 86400. The same page recommends starting with mode: testing on an existing domain and monitoring TLS-RPT reports for a few weeks first, so follow that advice.

How to check it worked

Run these checks after each stage. All of them use the made-up example.com, so swap in your domain.

This command shows your TLS-RPT record.

dig TXT _smtp._tls.example.com +short

You should see "v=TLSRPTv1; rua=mailto:tlsrpt@example.com".

This command shows your discovery record.

dig TXT _mta-sts.example.com +short

You should see "v=STSv1; id=..." with your current id. On the Cloudflare route, Cloudflare's docs show the answer coming back through the CNAME, with _mta-sts.mx.cloudflare.net carrying the TXT value.

This command downloads the policy itself.

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

You should see your version, mode, mx lines and max_age, with no HTML around them.

Finally, check the tlsrpt@example.com mailbox a day or two after Step 2. Reports from large senders should start to appear as JSON attachments. Each one should cover a full UTC day, so do not expect them within the hour.

Troubleshooting

Reports show "certificate" failures for one MX host

Symptom: most sessions succeed, but one MX host collects failures with a certificate reason. Likely cause: that server's certificate is expired, does not match its host name, or does not chain to a trusted root. The RFC requires the certificate to be unexpired, to chain to a trusted root and to match the host name. Fix: ask whoever runs that mail server to renew or correct the certificate, then watch a few more days of reports.

Reports say the policy could not be fetched

Symptom: failures mention the policy fetch, or no sender seems to use your policy. Likely cause: the file returns a redirect, a 404, or an HTML error page. Fix: run curl -I on the policy URL and make sure the first line shows 200 with no Location header. Remove any site-wide redirect for the mta-sts subdomain.

The certificate on mta-sts.example.com is wrong or missing

Symptom: curl prints a certificate error. Likely cause: the subdomain is using the main site's certificate, or no certificate at all. Fix: issue a certificate that covers mta-sts.example.com exactly, and confirm it renews automatically.

You changed the policy but senders keep using the old one

Symptom: you edited mta-sts.txt but reports still reflect the previous policy. Likely cause: you did not change the id in the _mta-sts TXT record, so senders had no reason to fetch again. Fix: publish a new id, after the file is updated.

Mail started bouncing after you enforced

Symptom: senders report delivery failures soon after the switch. Likely cause: an MX host missing from the policy, often after a provider change. Fix: add the missing mx line, or set mode: testing, upload the file, then publish a new id. Senders that cached the old policy may keep it until its max_age runs out, since the RFC says clients "SHOULD cache a policy for up to this value." This is why short values help early on.

Nothing happens at all after adding the discovery record

Symptom: no reports, no sign of policy use. Likely cause: DNS has not spread yet, or senders checked before the file was ready. Google says DNS changes can take up to 24 hours. The UK guidance warns that if senders do not find the file on their first few checks, "they will back off and sometimes not look again for periods up to 4 weeks." Fix: confirm both dig checks and the curl check pass, then be patient.

If you ever need to turn it off

Do not simply delete the records. RFC 8461 section 8.3 describes the clean way out: publish a policy with mode: none and a small max_age, publish a new TXT record (with a new id) so senders fetch it, and only remove the TXT record and the HTTPS file after all previously served policies have expired. The RFC says senders treat a none policy as though there is no active policy.

The one message worth forwarding

Copy this to whoever looks after your domain or email:

"Hi, I would like to set up MTA-STS and TLS-RPT for example.com so other mail servers must use encrypted, authenticated connections to deliver to us. Plan: back up the DNS zone, add a TLS-RPT TXT record at _smtp._tls.example.com pointing to tlsrpt@example.com, publish a testing-mode policy at https://mta-sts.example.com/.well-known/mta-sts.txt listing our current MX hosts, wait 48 hours, add the _mta-sts TXT record, and watch reports for at least two weeks before we enforce. Can you confirm our current MX host names and whether you can serve that file over HTTPS with no redirect?"

Start with the TLS-RPT record today, because it takes five minutes, cannot break anything, and tells you exactly what you need to know before you enforce.

Reader questions

Does MTA-STS protect email I send to other people?

No. Your MTA-STS policy tells other servers how to deliver mail to your domain. Outbound protection depends on the receiving domain publishing its own policy.

Will turning on TLS-RPT affect my mail delivery?

No. The TLS-RPT TXT record only asks sending servers to email you reports about their connection attempts. It does not change how mail is delivered.

How long should the id value in the `_mta-sts` record be?

RFC 8461 allows 1 to 32 letters or digits. Google suggests using the current date and time, and the value must change every time the policy changes.

What is the largest `max_age` I can set?

RFC 8461 sets a maximum of 31557600 seconds. Short values are safer while you are still testing, because senders may cache a policy for up to `max_age`.

Do I need DNSSEC for MTA-STS to work?

No. MTA-STS fetches its policy over HTTPS, which Cloudflare's documentation notes is used because not everyone uses DNSSEC.

Can I list a wildcard like *.example.net in the policy?

RFC 8461 allows a wildcard only as the whole leftmost label. The UK government guidance advises against wildcard MX entries and recommends full host names.

Sources & further reading

  1. RFC 8461: SMTP MTA Strict Transport Security (MTA-STS)
  2. RFC 8460: SMTP TLS Reporting
  3. Google Workspace: About MTA-STS and TLS reporting
  4. Google Workspace: Turn on MTA-STS and TLS reporting
  5. Google Workspace: Create an MTA-STS policy
  6. Google Workspace: Publish your MTA-STS policy
  7. GOV.UK Security: Set up TLS-RPT and MTA-STS
  8. Cloudflare Email Service: MTA-STS

Originally published . About our editorial updates.

Your next project deserves a better foundation.

Explore hosting built for your next chapter.

Explore hosting

Find your next answer.

Search published guides and articles.

Ctrl / ⌘ K to open · Esc to close