HomeBlog › TLS configuration

Expiring and weak TLS: what breaks, and what to check

A certificate does not degrade. It works completely, and then at a precise moment it does not work at all - usually on a weekend.

TLS certificate illustration: a mountain path marked with three waypoints for checking your configuration, disabling old protocols such as SSL and TLS 1.0 and 1.1, and renewing on time, above a panel showing a valid certificate with its issue and expiry dates.

Of everything visible from outside your domain, TLS is the one with the shortest distance between "misconfigured" and "customers cannot use the product". There is no grace period and no partial failure. The certificate is valid until the second it is not.

What actually breaks

When a certificate lapses, the failure is not cosmetic and it is not limited to browsers.

  • Browsers present a full-page warning. A proportion of visitors will click through; most will not, and some will conclude the company has gone under.
  • API clients simply refuse to connect. Libraries validate certificates by default, so integrations fail with a TLS error rather than an HTTP error - which makes the cause less obvious to whoever is debugging it.
  • Webhooks stop being delivered. Payment providers, CI systems and anything else calling into you will fail and, depending on the sender, may stop retrying.
  • Mobile apps break hardest, particularly with certificate pinning, and cannot be fixed without a release.

Renewal is usually a few minutes of work. The time is spent diagnosing, because the first symptom is often "the app is down" rather than anything mentioning certificates.

Expiry, and why automation is not quite enough

Automated issuance made expiry a mostly solved problem. Certificates renew on a schedule, unattended, and the majority of the time nobody thinks about it.

The remaining risk is that automated renewal fails quietly. The common causes:

  • The HTTP validation path stops being reachable - a redirect rule, a new WAF rule, or a firewall change blocks the challenge.
  • DNS validation breaks after a nameserver migration.
  • The renewal job lives on a host that was rebuilt, and the cron entry did not come with it.
  • The certificate covers a hostname that no longer resolves, so validation cannot complete for that name.

In each case the renewal fails, the failure is logged somewhere nobody reads, and the existing certificate keeps working right up until it does not. This is why expiry remains worth monitoring externally even when renewal is automated: an external check sees the certificate the world sees, not what your renewal script believes it did.

Protocol versions and what to turn off

Your server advertises which protocol versions it will accept, and that list is readable by anyone who connects.

  • TLS 1.3 - current, fastest, fewest options to get wrong. Enable it.
  • TLS 1.2 - still fine and still widely needed. Keep it.
  • TLS 1.1 and 1.0 - deprecated. Disable both.
  • SSL 3.0 and earlier - broken for years. Should not be reachable at all.

Disabling the deprecated versions is usually a one-line configuration change, and modern clients negotiate 1.2 or 1.3 anyway. The exception is if you serve unusual legacy clients - embedded devices, very old enterprise systems - in which case the decision needs a look at your actual traffic rather than a rule of thumb.

The redirect nobody checks

Supporting HTTPS is not the same as requiring it. If http://yourdomain.com still serves content rather than redirecting, then any visitor who types your domain without a scheme gets one unencrypted round trip before anything else happens.

Two settings close that gap. The redirect itself:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

And HSTS, which tells the browser to use HTTPS for your domain from now on without asking:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

HSTS is covered alongside the other headers in the security headers that actually matter. One caution: includeSubDomains applies to every subdomain, so make sure they all serve HTTPS before you publish it.

The chain, and the part that fails only for some visitors

A certificate is presented with intermediates that link it back to a trusted root. If your server omits an intermediate, some clients will still work - browsers often fetch the missing certificate themselves or have it cached - while others fail outright.

This produces the worst kind of bug report: it works on every machine in the office and fails for a particular customer's integration. The cause is an incomplete chain, and it is invisible until you test from a client that does not paper over it.

# the chain as actually served; each "s:" should link to the next "i:"
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null   | grep -E '^ *[0-9]+ s:|^ *i:'

Most automated issuance produces a complete chain. Manual installation, and copying a certificate between servers by hand, is where intermediates get dropped.

Monitoring that actually catches it

The failure mode worth designing against is nobody noticing until a customer calls. Three levels, in increasing order of usefulness:

  • Calendar reminder. Better than nothing, worse than it sounds - it goes stale the moment renewal dates shift.
  • Automated renewal with failure alerting. The renewal is automatic; the alert fires when it fails. The alert is the part people forget, and it is the part that matters.
  • External expiry monitoring. Something outside your infrastructure connects and reads the date on the certificate actually being served. This is the only one that catches the case where renewal succeeded but the new certificate was never loaded, or was loaded on one server out of three.

That last case is more common than it should be. A renewal writes a new certificate to disk, nothing reloads the web server, and the old certificate keeps being served until it expires - at which point the logs show a successful renewal and the site is down anyway.

Reading your own configuration

Everything here is visible from any machine with openssl:

# issuer, subject and validity dates
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
  | openssl x509 -noout -issuer -subject -dates

# does a deprecated version still negotiate? (a failure here is the good result)
openssl s_client -connect yourdomain.com:443 -tls1_1 2>&1 | grep -E "Protocol|alert"

# does HTTP redirect?
curl -sI http://yourdomain.com | head -3

Check the expiry date on every hostname you serve, not just the apex. A certificate covering yourdomain.com does not necessarily cover www.yourdomain.com, and subdomains often renew on their own schedule through a different mechanism entirely.

What a scan can and can't confirm here. An external check reads the certificate presented on the hostname it was given - issuer, expiry, and whether HTTP redirects - and that is exactly what a visitor sees. What it does not cover: other hostnames you did not ask it to check, internal services not exposed publicly, certificate pinning in your mobile apps, or whether your private key has ever been handled carelessly. A passing TLS check means the public endpoint tested was configured correctly at that moment.

Worth doing once, properly

TLS is unusual among the items on an external report in that it is almost entirely solvable with configuration, and then it stays solved. Enable 1.2 and 1.3, disable the rest, force the redirect, publish HSTS, and monitor expiry on every hostname from outside your own infrastructure.

After that it should only ever appear on a report as a passing check - which, given that it sits directly in front of every login and every API call you serve, is where you want it. It is one signal among several in your external security posture, and one of the few where the failure mode is immediate and total.

Questions people ask about this

What happens when a TLS certificate expires?

Browsers show a full-page interstitial warning that most visitors will not click through, and programmatic clients - API consumers, mobile apps, webhooks, payment integrations - refuse the connection outright. There is no partial degradation: it works, and then it does not.

Which TLS versions should I still support?

TLS 1.2 and TLS 1.3. TLS 1.0 and 1.1 are deprecated and no longer considered adequate; SSL 2.0 and 3.0 have been broken for years. Modern clients all negotiate 1.2 or 1.3, so disabling the older versions rarely breaks anything current.

Does automatic renewal mean I can stop worrying about expiry?

Mostly, but not entirely. Automated renewal fails quietly in specific situations: the validation challenge stops being reachable, a DNS change breaks verification, or the renewal cron dies on a host nobody monitors. The first you hear of it is the outage, so monitoring expiry is still worthwhile even with automation.

Is a free certificate less secure than a paid one?

No. The encryption is identical. Paid certificates may include organisational validation, warranties or support, but a free domain-validated certificate from a public CA provides the same cryptographic protection and the same browser trust.

Check your certificate and protocol support

See your issuer, expiry date, whether HTTP redirects to HTTPS, and which protocol versions you still accept.

Run a free check