Opyntel

SSL certificate expired: why it happened and how to renew it

When an SSL certificate has expired, browsers block the site with NET::ERR_CERT_DATE_INVALID or “Your connection is not private”, and API clients refuse to connect. Confirm the expiry date with openssl, renew the certificate (certbot renew, your reverse proxy or your platform), and reload whatever serves it. Certificates from Let’s Encrypt are short-lived and renew themselves, so an expired one almost always means the automatic renewal failed quietly weeks before.

Check when the certificate expires

bash
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates -issuer -subject

notAfter is the expiry date, and issuer shows who issued it. If the issuer is “TRAEFIK DEFAULT CERT” or the subject names another domain, the server never got a real certificate for this name; that is a missing certificate, not an expired one. On a server that uses Certbot, sudo certbot certificates lists every certificate with its expiry.

Why automatic renewal failed

CauseHow to tell
The renewal timer stoppedsystemctl list-timers | grep certbot shows no timer (and there is no /etc/cron.d/certbot), or the server was rebuilt without it
Port 80 is closedThe HTTP-01 challenge needs port 80 open to the internet; a firewall rule added later blocks renewal
DNS movedThe domain now points at another server, a load balancer or a CDN, so the challenge never reaches you
A CAA record excludes the issuerdig CAA example.com
Renewed, but not reloadedThe new certificate is on disk but nginx or the app still serves the old one from memory
Rate limitsToo many failed attempts for the same name; the renewal log says so

Renew the certificate

Certbot on a VPS:

bash
sudo certbot renew --dry-run     # test first; shows the error if renewal would fail
sudo certbot renew
sudo systemctl reload nginx       # or apache2, or whatever serves the certificate

Traefik, the proxy in Coolify and Dokploy, requests and renews certificates itself once the domain resolves to the server and port 80 is open. Its log says why a request failed:

bash
docker logs coolify-proxy 2>&1 | grep -i acme      # Coolify
docker logs dokploy-traefik 2>&1 | grep -i acme    # Dokploy

Platforms such as Vercel, Netlify, Cloudflare and DigitalOcean App Platform issue and renew certificates for you while the domain’s DNS points at them. When one lapses there, check that the DNS records still match what the platform’s domain settings ask for, and that no CAA record blocks its issuer.

Stop it happening again

Run certbot renew --dry-run after any firewall, DNS or proxy change, keep port 80 open for the challenge, and add a reload hook (--deploy-hook "systemctl reload nginx") so a renewed certificate is actually served. Renewal failures are silent, so the safeguard that matters is an alert on the expiry date itself, from outside the server, well before the day. A site that goes down for other reasons is covered in 5xx errors explained.

How Opyntel catches a certificate before it expires

Opyntel’s uptime checks call each public URL you add and read the certificate it serves on every check. Opyntel alerts when a certificate gets closer to its expiry than the number of days you set, and when an endpoint stops answering, by email, Slack or SMS depending on your plan. Every endpoint sits in one dashboard next to the services and servers behind it, so a renewal that failed quietly shows up before your visitors see a warning.

FAQ

SSL certificate expired questions, answered

What an expired certificate breaks, renewing early and certificates that look renewed.

Browsers show a full-page warning and most visitors leave; API clients and webhooks refuse to connect until the certificate is renewed.

openssl s_client piped into openssl x509 -noout -dates prints the notAfter date of the certificate a server serves.

The server still serves the old certificate from memory. Reload nginx, Apache or the proxy, and clear any CDN that caches it.

Yes. certbot renew renews certificates close to expiry; certbot renew --force-renewal renews them all now.

The alerts your platform doesn’t send.

One dashboard for everything you run, with the alerts your platforms leave out. Read-only, nothing to install in your apps.

See how it works