STARTTLS negotiation failures happen all the time. A misconfigured certificate, an expired root CA, a cipher suite mismatch, a downgrade attack. The sending server falls back to plaintext, the message goes through, and you never know it happened.

TLS-RPT (RFC 8460) gives you visibility into those failures. It's the STARTTLS equivalent of DMARC aggregate reports: sending mail servers that support TLS-RPT will send you JSON reports documenting when TLS negotiation with your MX hosts failed, what the failure mode was, and how many messages were affected.

Most organizations don't know it exists. If you're running email infrastructure, you should enable it.

How TLS-RPT Works

TLS-RPT is a feedback mechanism for SMTP TLS policy. When a sending mail server tries to deliver to your domain and encounters a TLS failure, it generates a report and sends it to the address you specify in your TLS-RPT DNS record.

The flow:

  1. Your domain publishes a TLS-RPT record at _smtp._tls.yourdomain.com with a reporting address.
  2. A sending mail server attempts TLS negotiation with your MX host.
  3. If negotiation fails (certificate error, protocol mismatch, policy mismatch, etc.), the sender logs the failure.
  4. The sender aggregates failures and sends a daily JSON report to your designated address.

Reports arrive as email messages with a gzip-compressed JSON attachment. The JSON contains detailed failure data: which policy was in play, what went wrong, how many attempts failed, and during what time window. The policy-type field takes three values: sts for MTA-STS, tlsa for DANE, and no-policy-found when the sender discovered neither. Reports still arrive in that third case, which catches people out when they read their first one.

Publishing a TLS-RPT Record

The DNS record is simple:

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

The rua (reporting URI aggregate) field specifies where reports should be sent. You can list multiple addresses separated by commas. HTTPS endpoints are also supported (rua=https://example.com/tls-rpt), but email is far more common.

Most organizations use a subdomain or dedicated mailbox for TLS reports. Parse the JSON with a script, log failures to your monitoring stack, or use a third-party service to aggregate and visualize the data.

You can verify your DNS record with the DNS lookup tool on mrdns.com, which supports TXT record queries for _smtp._tls records.

Reading the JSON Reports

TLS-RPT reports are verbose but structured. Here's a minimal example:

{
  "organization-name": "Sending MTA Inc",
  "date-range": {
    "start-datetime": "2026-04-27T00:00:00Z",
    "end-datetime": "2026-04-28T00:00:00Z"
  },
  "contact-info": "postmaster@sendingmta.example",
  "report-id": "2026-04-27-abc123",
  "policies": [
    {
      "policy": {
        "policy-type": "sts",
        "policy-string": ["version: STSv1","mode: enforce","mx: mail.example.com","max_age: 86400"],
        "policy-domain": "example.com"
      },
      "summary": {
        "total-successful-session-count": 1523,
        "total-failure-session-count": 7
      },
      "failure-details": [
        {
          "result-type": "certificate-expired",
          "sending-mta-ip": "203.0.113.45",
          "receiving-mx-hostname": "mail.example.com",
          "receiving-ip": "198.51.100.10",
          "failed-session-count": 4,
          "failure-reason-code": "X509_V_ERR_CERT_HAS_EXPIRED"
        },
        {
          "result-type": "starttls-not-supported",
          "sending-mta-ip": "203.0.113.67",
          "receiving-mx-hostname": "backup-mx.example.com",
          "receiving-ip": "198.51.100.20",
          "failed-session-count": 3
        }
      ]
    }
  ]
}

The fields worth understanding: date-range gives you the reporting window, usually 24 hours. total-successful-session-count is your baseline: a handful of failures against 10,000 successful sessions is noise; the same handful against 50 successful sessions is not. The actual investigation lives in failure-details: result-type tells you what broke, receiving-mx-hostname and receiving-ip tell you which of your MX hosts had the problem, and failed-session-count tells you how many delivery attempts it affected.

What Failure Events Mean

certificate-expired is the obvious one: your certificate expired. Renew it. If you're using Let's Encrypt or another ACME provider, check whether automation actually ran: a renewal failure that went unnoticed for weeks is one of the most common explanations. Continuous certificate monitoring on your mail hosts catches that silent renewal failure before it reaches this report.

certificate-not-trusted means the chain is broken. Most often a missing intermediate certificate, an untrusted root CA, or a self-signed cert. Verify the chain with openssl s_client -connect mail.example.com:25 -starttls smtp, or use the SSL certificate checker on mrdns.com to inspect the full chain, expiry, SANs, and validation status.

certificate-host-mismatch means the certificate your MX host presented doesn't cover the MX hostname the policy names. It has its own result-type, and it is one of the most common failures in practice: a shared mail host serving a certificate for a different name, or an MX record renamed without reissuing the certificate.

validation-failure is the catch-all for X.509 and TLS errors that don't fit any of the categories above. Check the failure-reason-code field for the specific error string. The additional-information field, where a sender populates it, holds a URI pointing at further detail.

starttls-not-supported means your MX host didn't advertise STARTTLS. If you're enforcing TLS with MTA-STS, this is a misconfiguration, and it will keep failing until you fix it.

tlsa-invalid appears when you're running DANE. Your TLSA record doesn't match the certificate your MX host is presenting. Verify both the record and the fingerprint are current.

Don't go hunting for a timeout result-type. RFC 8460 doesn't define one, and a connection that dies before TLS negotiation starts falls outside the failure categories TLS-RPT reports on. Handshake problems that do get reported land under validation-failure with a failure-reason-code naming the error. Network and server-load problems on your MX hosts need to come from your own monitoring.

Why TLS-RPT Matters

STARTTLS is opportunistic. When negotiation fails, most MTAs silently fall back to plaintext, the message goes through, and you see nothing. TLS-RPT is how you find out: a daily account of every failed negotiation attempt against your MX hosts, what broke, and how many messages were affected.

Combined with MTA-STS, it closes the loop. MTA-STS tells sending servers they must use TLS. TLS-RPT tells you what happened when they tried.

Enable the DNS record, set up a mailbox, parse the JSON, and watch for failures. Most of the time you'll see nothing. When you do see something, it's worth knowing about.

Back to Blog