← All articles

The TLS certificate nobody was watching

August 7, 2026 · Wilson Santos
On this page

Ask a security team about TLS and you will hear about protocol versions, cipher suites and downgrade attacks. Ask an operations team and you will hear about the Sunday morning a certificate expired.

Both are TLS problems. Only one of them happens regularly.

The failure mode that fires

An expired certificate is not a degradation. Browsers refuse the connection outright, API clients throw, and the service is down for everyone at once. There is no partial availability and no graceful path. The failure is total and instantaneous, at a moment determined months earlier by somebody who has probably changed teams.

It is also, uniquely among outages, known in advance to the second. The expiry date is printed in the certificate. Nothing else in operations gives you that much warning and gets ignored so reliably.

Every other outage

Arrives without notice. The work is detection, and the money goes on noticing faster: monitoring, alerting, someone carrying a pager.

This one

The date is printed inside the certificate. Months of warning, readable by anything that opens a connection, and nothing in the pipeline opens one.

The reason it gets ignored is ownership. A certificate is issued during a project, by whoever was setting the thing up, and then belongs to nobody. Automated renewal solves it where it is deployed, and there is always something outside that: an internal service on a corporate CA, a partner's mutual-TLS endpoint, a load balancer somebody configured by hand, a certificate pinned into a mobile app.

Why "the padlock is green" is not a check

The browser tells you the certificate is valid for the name you typed, from a CA your machine trusts, right now. Three conditions, all of which can be true while something is wrong:

  • It expires in nine days. The padlock looks identical on day 90 and day 1.
  • It is valid for www.example.com and your API is on api.example.com. Fine in the browser you tested; broken for the client you did not.
  • The chain is incomplete. Browsers often repair this by fetching the intermediate. curl, Java clients and mobile stacks frequently do not, so it works for you and fails in production for somebody else.
  • The endpoint still accepts TLS 1.0. Nothing visible to a user, and it is what a compliance questionnaire will ask about.
One indicator, four different faults A browser reports a secure connection identically in all four cases. The certificate that expires in nine days looks the same as one with ninety. A certificate for www does not cover api. An incomplete chain is repaired by browsers and not by other clients. An endpoint still offering TLS 1.0 shows nothing to a user at all. WHAT THE BROWSER SHOWS SecureSecure SecureSecure WHAT IS ACTUALLY TRUE Expires in 9 days Day 90 and day 1 draw the same padlock. Wrong name Covers www, and your API is on api. Chain incomplete Browsers fetch the missing link. curl and Java clients do not. TLS 1.0 accepted Nothing a user could see, and the first thing an auditor asks. The indicator is the same in all four. It was answering a narrower question than the one being asked of it.
A browser reports that this certificate is valid for the name you typed, from a CA you trust, at this moment. All three can hold while the thing is broken for somebody else.

Every one of those passes the eye test.

The configuration drifts even when nothing changes

This is the part that surprises people. A TLS configuration that was excellent when it was written gets worse without anybody touching it, because the standard moves underneath it.

Cipher suites considered fine become deprecated. Protocol versions get formally retired. A configuration copied from a good blog post in 2019 is not a good configuration now, and nothing in the deployment will mention it. The service keeps serving.

The same configuration, two verdicts One configuration enabling TLS 1.0 through 1.2 with an RSA cipher suite. When it was written it was a good configuration. The identical text later offers two retired protocol versions and a suite without forward secrecy. Nothing was edited between the two readings. WHEN IT WAS WRITTEN protocols TLSv1 TLSv1.1 TLSv1.2 ciphers AES256-SHA A good configuration Everything current was enabled. THE SAME FILE, LATER protocols TLSv1 TLSv1.1 TLSv1.2 ciphers AES256-SHA Two retired versions, no forward secrecy The standard moved. The file did not. Not one character differs between these two panels. No deployment, no commit, and no alert marks the moment one became the other.
Every other control tells you something changed. This one degrades while the thing it describes sits still, which is why it has to be re-asked rather than reviewed once.

So the check has to be periodic, not a one-time review. It is closer to a smoke test than to an audit.

What is worth checking, in order

CheckWhy it is missed
1Expiry, with enough warning to act. Thirty days is a reasonable floora renewal can need an approval, and the warning is worthless if it arrives after the last person who can sign
2Name validity for the name clients use, every alternative namethe one name somebody tested is the one name that works
3Chain completenessthe browser repairs it, so the person checking is the least likely to see it
4Protocol versions offerednothing stops working when an old one stays enabled, so nothing prompts anybody

That is a short list, and it is nearly the whole value. TLS is unusual among security controls in having a small, checkable, high-consequence surface.

Where it fits in a pipeline

TLS is checked against a running endpoint, so it does not belong in a code scan. It belongs wherever you check things about deployed services, on a schedule rather than on a commit.

Draugr's tls control probes each host a component declares and reports expiry, name validity, chain and protocol support natively, without shelling out to another tool. It is a small enough surface to do directly, and doing it directly means one less binary on the machine.

The TLS assessment guide covers the mechanics, and HTTP security headers is the other half of what is worth checking about a live host.