TLS-RPT Generator
The most harmless record in mail security: it forbids nothing and changes nothing about delivery, it simply asks for reports about failed attempts to encrypt a connection when delivering mail to your domain.
Either a mail address or an https endpoint. Reports arrive daily and describe failed attempts to establish an encrypted connection to your server.
Generated record
v=TLSRPTv1; rua=mailto:| Type | Name | TTL |
|---|---|---|
| TXT | _smtp._tls | 3600 |
What TLS-RPT is and why you want it
TLS-RPT (SMTP TLS Reporting, RFC 8460) tells you how other servers connect to yours. Servers that deliver mail to your domain send a daily summary: how many connections to your MX hosts went over TLS, how many failed, and why. It covers inbound mail, not the mail you send.
Those failures are invisible from the inside. A certificate expires, the name in it stops matching the server, an intermediate hop strips STARTTLS, and the sender delivers the message unencrypted or not at all, and you never find out. A downgrade attack looks the same. Someone in the middle deletes the “250 STARTTLS” line from the server's response, and the receiving server may not notice. TLS-RPT turns that blind spot into a daily report. It matters most alongside MTA-STS: the policy demands TLS, and the reports show who could not comply.
Where to publish it and what the record contains
As a TXT record at _smtp._tls.yourdomain. In most DNS panels the name field only needs _smtp._tls. Both underscores are required, and the order matters: nobody will look for a record at _tls._smtp.
v=TLSRPTv1; rua=mailto:tlsrpt@example.com,https://tlsrpt.example.com/reportThere are two tags. v=TLSRPTv1 sets the version and comes first. rua= says where reports go: mailto:, or https: for delivery by POST, with several addresses separated by commas. A sender may deliver to just one of them, so put the main address first. Unlike DMARC, another domain does not have to authorise receiving reports. RFC 8460 considers the abuse risk lower here.
There must be exactly one record starting with v=TLSRPTv1. With two, senders treat the domain as not using TLS-RPT at all. To check the published record:
dig +short TXT _smtp._tls.example.comWho sends the reports
Not everyone does. According to URIports as of August 2024, the largest senders of reports are Google, Microsoft, Comcast, Mail.ru and Mimecast. The same source notes that Microsoft delivers a report only to the first address in rua, which the standard permits.
By the standard, a report email carries the sender's DKIM signature, and an unsigned report should be ignored. It is delivered even when TLS fails, which means sometimes unencrypted, since otherwise nobody could report that encryption is broken.
What the JSON report contains
A report covers one UTC day and arrives a few hours later, usually gzip-compressed. A shortened example:
{
"organization-name": "Example Sender",
"date-range": {
"start-datetime": "2026-09-16T00:00:00Z",
"end-datetime": "2026-09-16T23:59:59Z"
},
"policies": [{
"policy": { "policy-type": "sts", "policy-domain": "example.com" },
"summary": {
"total-successful-session-count": 1285,
"total-failure-session-count": 3
},
"failure-details": [{
"result-type": "certificate-expired",
"sending-mta-ip": "198.51.100.7",
"receiving-mx-hostname": "mail.example.com",
"receiving-ip": "203.0.113.10",
"failed-session-count": 3
}]
}]
}organization-namenames the reporter, anddate-rangeshows which day the report covers.policy-typeshows which rule the connection was checked against:stsfor MTA-STS,tlsafor DANE, orno-policy-foundwhen there is none.total-successful-session-countandtotal-failure-session-countin thesummaryblock count successful and failed sessions. Those are the numbers to chart.failure-detailsholds a line per cause: the failure type, the sender's IP, your MX name and IP, and the number of failed sessions infailed-session-count.
Failure types and what to do about them
starttls-not-supported: the MX did not offer STARTTLS. If it is a backup server, fix it too, since mail goes there whenever the primary is down.certificate-expired: the MX certificate has expired, usually because auto-renewal failed.certificate-host-mismatch: the name in the certificate does not match the MX name, for example an MX ofmail.example.comwith a certificate issued forexample.com.certificate-not-trusted: the certificate does not chain to a trusted authority, most often because it is self-signed.validation-failure: a catch-all for anything else. The sender adds details infailure-reason-code, and you can see what your server presents in the SMTP test.sts-policy-fetch-error,sts-policy-invalid,sts-webpki-invalid: the MTA-STS policy could not be fetched or parsed, or the policy site has a certificate problem.tlsa-invalid,dnssec-invalid,dane-requiredare DANE failures: a bad TLSA record, an invalid DNSSEC answer, or no TLSA where the sender requires DANE.
The standard does not require reporting transient failures such as timeouts, so every line in a report deserves a look.
What to look at first
Isolated failures happen: networks, somebody's broken relay. The warning sign looks different: a steady share of failures from one sender, or certificate-expired rising everywhere at once, which usually means a certificate on your MX that failed to renew.
Reports also catch starttls-not-supported from hosts you believed were protected. The usual culprit is a gateway or anti-spam proxy stripping STARTTLS from the server's response. And then there is the backup MX: the primary is configured perfectly, the secondary has lived with an old certificate for years, and the errors only show up when the primary is unavailable.
How to process the reports
For the first few weeks, reading reports by hand works fine. This command prints the domain, the totals and the list of failures for each report:
gunzip -c report.json.gz | jq -c '.policies[] | {
domain: .policy."policy-domain", summary,
failures: [."failure-details"[]? | {type: ."result-type",
mx: ."receiving-mx-hostname", n: ."failed-session-count"}]}'After that, either send reports to an analysis service such as URIports or Mailhardener (just put its address in rua) or set up a rule: a message with a non-zero total-failure-session-count goes to a separate folder and the rest is ignored.
No reports at all is a signal too. If a week passes without a single report from Google or Microsoft, the record is probably at the wrong name, or there are two of them.
The order to roll out transport security
TLS-RPT goes first, because it is the only piece that cannot break anything. Reports accumulate and delivery stays the same. A week of observation gives you a baseline: how many connections use TLS at all, and from whom.
Next comes MTA-STS in testing mode: the reports show where the policy and reality disagree, and before you switch to enforce you can see which MX host will fail validation. Only after a clean week do you move to enforce, built in the MTA-STS generator. The reverse order means mail stops arriving and you have no data to tell you why.
Sources
- RFC 8460, section 1: downgrade by stripping STARTTLS
- RFC 8460, section 3: the _smtp._tls record and rua addresses
- RFC 8460, section 4.1: report time frame
- RFC 8460, section 4.3: result types
- RFC 8460, section 4.4: JSON report schema
- RFC 8460, section 7: why external destinations need no verification
- URIports: who sends reports and how Microsoft handles rua
- URIports: receiving TLS-RPT reports
- Mailhardener: SMTP TLS report aggregation
Questions
Nearby
Channel reports are not list quality
TLS-RPT tells you about connection problems, not about half your list being dead addresses. uChecker checks that before you send, and the first 100 addresses are free.
Check your list