TLS-RPT — Reporting Channel for MTA-STS

TLS-RPT — reporting channel for MTA-STS

TLS-RPT is the reporting standard that pairs with MTA-STS. It tells sending servers where to send reports when TLS negotiation fails. Without it, MTA-STS deployment is fire-and-forget — you have published a policy and have no idea whether anyone is actually failing against it.

The check is small. The record is small. The point is operational visibility.

What the record looks like

A TXT record at _smtp._tls.{domain}:

_smtp._tls.isidoregroup.com.  3600  IN  TXT  "v=TLSRPTv1; rua=mailto:tls-reports@isidoregroup.com"

Two tags:

  • v=TLSRPTv1 — version identifier. Required.
  • rua= — where to send reports. Either a mailto: URI or an https: URI. Multiple values comma-separated.

That is the entire spec. There is no policy field, no enforcement, no max_age. The record exists solely to point reporters at an address.

The hostname pattern is _smtp._tls.{domain} — two underscored labels, in that order. Easy to mistype; double-check.

What the reports contain

Sending mail servers that fail to negotiate TLS or fail MTA-STS validation produce a JSON report and send it daily to the rua address. The structure:

{
  "organization-name": "Google Inc.",
  "date-range": {
    "start-datetime": "2024-05-12T00:00:00Z",
    "end-datetime": "2024-05-13T00:00:00Z"
  },
  "contact-info": "smtp-tls-reporting@google.com",
  "report-id": "2024-05-13T00:00:00Z_isidoregroup.com",
  "policies": [
    {
      "policy": {
        "policy-type": "sts",
        "policy-string": ["version: STSv1", "mode: enforce", "mx: *.mail.protection.outlook.com", "max_age: 86400"],
        "policy-domain": "isidoregroup.com"
      },
      "summary": {
        "total-successful-session-count": 142,
        "total-failure-session-count": 3
      },
      "failure-details": [
        {
          "result-type": "certificate-expired",
          "sending-mta-ip": "40.92.4.21",
          "receiving-mx-hostname": "isidoregroup-com.mail.protection.outlook.com",
          "failed-session-count": 3
        }
      ]
    }
  ]
}

The fields you read most:

  • total-successful-session-count vs. total-failure-session-count — the ratio tells you whether the policy is operating cleanly.
  • failure-details[].result-type — the failure reason. Common values: certificate-expired, certificate-not-trusted, validation-failure, sts-policy-fetch-error.
  • failure-details[].sending-mta-ip — who tried to reach you and failed. Almost always identifies the sender side.

In practice, you will see a steady trickle of one-off failures (random misconfigured senders) and very occasionally a burst from one specific sender that points to a real interop problem. The trickle is normal; the burst is the signal.

What Cathedra reports

TlsRptCheck.php runs in three branches.

No TLS-RPT record

Field Value
status info
severity —
finding “No TLS-RPT record found at _smtp._tls.{domain}. SMTP TLS failure reporting is not configured.”
recommendation “Consider adding a TLS-RPT record to receive notifications about SMTP TLS failures.”

Same status discipline as MTA-STS — info, not warning. Missing TLS-RPT is an opportunity, not a defect. Most client domains will return this on first scan.

Record present with rua

v=TLSRPTv1; rua=mailto:tls-reports@isidoregroup.com
Field Value
status pass
severity —
finding “TLS-RPT record found with reporting address configured.”
recommendation —

Record present but missing rua

v=TLSRPTv1
Field Value
status warning
severity low
finding “TLS-RPT record found but no rua (reporting address) is set.”
recommendation “Add rua= with a mailto or HTTPS endpoint to receive TLS failure reports.”

This is the misconfiguration case. Someone published the record header without the address — the record is structurally present but operationally useless. Easy fix.

Why deploy TLS-RPT at all if MTA-STS is the security control

Two reasons.

1. MTA-STS without TLS-RPT is unobservable.
If MTA-STS is rejecting senders, you have no signal that it is happening. A new partner could be silently failing to deliver because their TLS configuration drifted; you would only find out when someone phones to ask why an email didn’t arrive. TLS-RPT turns those silent failures into reports.

2. TLS-RPT works without MTA-STS too.
The reports cover any TLS failure, not just MTA-STS validation failures. A sending server with broken TLS, an expired certificate on your MX, a downgrade attempt — all show up. Even on a domain that hasn’t deployed MTA-STS, TLS-RPT alone provides forward visibility on TLS hygiene.

For most clients we deploy them together. The cost is two TXT records and a forwarder.

Where to send the reports

Same posture as DMARC rua. We use an address under the client’s domain (tls-reports@{client}) that forwards to an Isidore-monitored shared mailbox, or a parsing service inbox. Never the client’s primary mail — TLS-RPT reports are operational telemetry, not communication.

If you are already running dmarcian or similar for DMARC, check whether the service also ingests TLS-RPT. Several do. Same mailbox, two different report types separated by content.

Cheat sheet

Condition Cathedra status Severity Finding
No record info — “No TLS-RPT record found at _smtp._tls.{domain}…”
Record + rua pass — “TLS-RPT record found with reporting address configured.”
Record, no rua warning low “TLS-RPT record found but no rua (reporting address) is set.”

What you should remember

  • TLS-RPT is a TXT at _smtp._tls.{domain} carrying v=TLSRPTv1; rua=....
  • Missing record is info, not warning. Same disposition as MTA-STS.
  • Record present without rua is warning / low. Useless without the address.
  • Reports come as daily JSON, summarizing successful and failed TLS sessions plus per-failure detail.
  • Deploy TLS-RPT alongside MTA-STS. Without it, MTA-STS is fire-and-forget.

Cathedra alignment: TlsRptCheck.php — the TXT record at _smtp._tls.{domain}