Why SSL Certificates Expire (and Why It Still Catches Teams Off Guard)
TLS certificates are intentionally time-limited. The CA/Browser Forum — the industry body that sets certificate policy — has progressively shortened the maximum validity period for publicly trusted certificates. Domain-validated (DV) certificates from most CAs are now capped at 398 days (roughly 13 months). Let's Encrypt issues 90-day certificates specifically to encourage automation and reduce the blast radius of a compromised private key.
Short lifespans are a security feature: they limit how long a compromised or mis-issued certificate remains trusted. But they create an operational burden — every certificate must be renewed on a regular cycle, and anything that disrupts that cycle causes an outage.
The reason expiry still catches experienced teams off guard, despite widespread awareness of the problem, comes down to three patterns:
Infrastructure drift. A server that was originally provisioned with working auto-renewal later has its networking changed, its firewall rules updated, or its DNS migrated. The renewal configuration that worked at provisioning time silently breaks months later — and nobody notices until the certificate expires.
Inventory gaps. Most monitoring covers the obvious domains. The subdomain that runs the customer-facing API, the staging environment with a valid cert that gets promoted to production traffic, the third-party SaaS integration that sends email from your domain — these often fall outside the monitoring inventory.
Multi-team ownership. When a certificate is provisioned by the infrastructure team, renewed by a devops script, and the domain is managed by the web team, nobody has clear ownership of the renewal lifecycle. Renewal failure notifications go to a shared inbox that nobody actively monitors.
How to Check Certificate Expiry Right Now
Before building monitoring, you need to know the current state of every certificate you're responsible for. Start with these methods.
Via browser
Click the padlock icon in the browser address bar, navigate to certificate details, and read the "Valid until" field. This is fine for a one-off check of a single domain but doesn't scale.
Via openssl from the command line
# Check expiry date for a domain
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
# Output:
# notBefore=Mar 1 00:00:00 2025 GMT
# notAfter=Mar 1 00:00:00 2026 GMT
# Check how many days until expiry
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -enddate \
| sed 's/notAfter=//' \
| xargs -I {} date -d "{}" +%s \
| xargs -I {} bash -c 'echo $(( ({} - $(date +%s)) / 86400 )) days remaining'
# Check a certificate file directly (not via live connection)
openssl x509 -in /path/to/certificate.crt -noout -dates
# Check all SANs (Subject Alternative Names) covered by the certificate
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text \
| grep -A1 "Subject Alternative Name"
The -servername flag is essential for servers hosting multiple domains via SNI — without it, you may get the wrong certificate back.
Via the SSL Certificate Checker
Use our SSL Certificate Checker to inspect any domain's certificate instantly — it shows expiry date, issuer, chain validity, SANs covered, and days remaining without requiring command-line access.
💡 Tip: When checking manually, always verify the SAN list on the certificate rather than just the common name. A certificate issued for
www.example.comdoes not automatically coverapi.example.comorexample.com(the bare domain) unless those names are explicitly listed in the Subject Alternative Names field.
Why Auto-Renewal Fails More Than You Think
Auto-renewal is not a set-and-forget solution. The following table covers the most common failure modes and how to prevent each one.
| Failure Cause | How It Happens | Prevention |
|---|---|---|
| DNS validation failure | DNS changed after cert was provisioned; ACME DNS-01 challenge record no longer resolvable | Monitor DNS health alongside cert expiry; re-validate DNS-01 credentials after any DNS migration |
| HTTP-01 challenge blocked | Firewall or CDN blocks /.well-known/acme-challenge/ path | Confirm the challenge path is reachable before relying on HTTP-01; use DNS-01 for wildcard certs |
| Port 80 not listening | Server only listens on 443; Let's Encrypt HTTP-01 requires port 80 accessible | Keep port 80 open and redirecting to HTTPS, or switch to DNS-01 |
| Certbot / ACME client not running | Cron job deleted, container restarted without renewal job, systemd timer disabled | Audit renewal cron/timers monthly; alert on last-successful-renewal timestamp |
| Rate limit hit | Too many failed renewal attempts exhaust Let's Encrypt rate limits (5 failures/hour) | Monitor for renewal errors immediately — failed attempts burn your rate limit budget |
| Certificate stored in wrong location | Renewal succeeds but web server still reads old cert from a different path | Verify web server cert path matches renewal output path; test after each renewal |
| Wildcard cert renewed but not deployed | Wildcard cert renewed on one server but not propagated to load balancer or CDN | Include deployment step in renewal automation; monitor all nodes, not just the primary |
| Commercial cert manual renewal missed | Renewal reminder email ignored, sent to wrong address, or caught by spam filter | Never rely solely on email reminders; use independent monitoring with 60-day and 30-day alerts |
⚠️ Warning: Wildcard certificates (
*.example.com) and multi-SAN certificates covering many hostnames require separate monitoring attention. A single certificate may cover 30 subdomains — if it expires, all 30 go down simultaneously. Never assume monitoring one domain on a wildcard cert means all covered domains are monitored.
A Production Monitoring Checklist for TLS Certificates
Use this checklist to establish or audit your certificate monitoring posture.
Inventory
- List every public-facing domain and subdomain that serves HTTPS traffic
- List every API endpoint, webhook receiver, and internal service with a TLS certificate
- Note which certificates are wildcards and which SANs each covers
- Record the issuer, renewal method (auto/manual), and responsible team for each cert
Expiry alerting
- Alert at 60 days remaining — enough time to resolve any renewal issues without urgency
- Alert at 30 days remaining — escalation trigger; manual intervention likely needed
- Alert at 14 days remaining — critical; should trigger incident response if not resolved
- Alert at 7 days remaining — P1 incident; service disruption imminent
Renewal verification
- Confirm auto-renewal runs successfully at least once after setup — don't assume it works
- Verify the renewed certificate is actually deployed to all servers and load balancers
- Test that the correct certificate is served after each renewal (
openssl s_clientor SSL Checker) - Log the timestamp of each successful renewal; alert if no renewal occurs within expected window
Coverage gaps
- Include non-production environments (staging, dev) if they handle real traffic or external integrations
- Monitor certificates on non-standard ports (8443, 8080 with TLS, internal services)
- Check certificates used for SMTP (port 587/465) and other non-HTTPS TLS services
- Verify monitoring covers all SANs on wildcard and multi-domain certificates
Setting Up Expiry Alerts: Methods and Tools
Command-line monitoring script
A simple bash script you can run as a cron job or in CI/CD:
#!/bin/bash
# Check SSL expiry and alert if under threshold
DOMAIN="example.com"
THRESHOLD_DAYS=30
EXPIRY=$(echo | openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "${EXPIRY}" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
if [ "$DAYS_LEFT" -lt "$THRESHOLD_DAYS" ]; then
echo "ALERT: ${DOMAIN} certificate expires in ${DAYS_LEFT} days (${EXPIRY})"
# Add your alerting mechanism here: email, Slack webhook, PagerDuty, etc.
fi
echo "${DOMAIN}: ${DAYS_LEFT} days remaining (expires ${EXPIRY})"
Run this script daily via cron for each domain in your inventory. Pipe the alert output to your notification system of choice.
Monitoring platform integrations
Most infrastructure monitoring platforms include native TLS certificate checks:
- Datadog — Synthetic Monitoring includes certificate expiry checks with configurable alert thresholds
- Prometheus + Blackbox Exporter — the
sslprobe module exportsprobe_ssl_earliest_cert_expiryas a metric; alert when it falls below your threshold in days - Grafana Cloud — built-in synthetic checks include certificate validity monitoring
- UptimeRobot / Better Uptime / Freshping — these uptime monitors include certificate expiry alerting in their SSL check feature
Let's Encrypt specific monitoring
# Check certbot renewal status
sudo certbot certificates
# Test renewal without actually renewing (dry run)
sudo certbot renew --dry-run
# Check systemd timer status for automated renewals
systemctl status certbot.timer
systemctl list-timers | grep certbot
Run certbot renew --dry-run monthly to confirm the renewal process works end-to-end before the certificate actually needs renewing.
What to Do When a Certificate Has Already Expired
If you're reading this because a certificate has already expired, follow these steps in order:
-
Confirm the expiry. Run the
openssl s_clientcommand or use the SSL Certificate Checker to confirm the certificate is expired and identify exactly which certificate is the problem. -
Identify the renewal method. Determine whether this is a Let's Encrypt certificate (check for certbot or acme.sh configuration), a commercial certificate (check with your CA or registrar), or a self-signed certificate.
-
For Let's Encrypt: Run
sudo certbot renew --force-renewalto force immediate renewal regardless of the normal renewal window. If this fails, check the error output — common causes are DNS validation failure and port 80 blocking. -
For commercial certificates: Log in to your CA's portal and initiate an emergency renewal. Most CAs offer expedited reissuance for expired certificates. You will need to complete a new validation challenge (DV, OV, or EV depending on certificate type).
-
Deploy immediately. After obtaining the new certificate, deploy it to your web server and reload the service. Verify the new certificate is being served before closing the incident.
-
Check HTTP Headers Check to confirm HSTS is not causing residual browser issues after the certificate is restored — in rare cases, HSTS preloading can cause browsers to refuse connections even after a valid certificate is in place.
⚠️ Warning: Do not request a new certificate without first fixing whatever caused the previous one to expire. If an ACME challenge fails, requesting another certificate will fail for the same reason — and repeated failures consume your rate limit budget, potentially locking you out of issuing new certificates for hours.
Certificate Transparency Logs as a Monitoring Signal
Certificate Transparency (CT) is a public infrastructure that records every certificate issued by publicly trusted CAs into append-only, publicly auditable logs. Every certificate issued for your domains — including ones you didn't issue — appears in these logs within seconds of issuance.
This creates a monitoring opportunity: by watching CT logs for your domains, you can detect:
- Certificates issued for your domains by CAs you didn't authorise (potential mis-issuance or attack)
- Upcoming certificate expirations across your entire domain footprint
- Certificates issued for subdomains you weren't aware were using TLS
Tools and services for CT log monitoring:
- crt.sh — Public CT log search. Query
https://crt.sh/?q=%.example.comto see all certificates ever issued for your domain and subdomains, including expiry dates. - Cert Spotter (SSLMate) — Free monitoring service that alerts you when new certificates are issued for your domains via CT logs.
- Facebook Certificate Transparency Monitoring — Meta's public CT monitoring tool at
developers.facebook.com/tools/ct
# Query crt.sh API for all certificates for a domain
curl -s "https://crt.sh/?q=%.example.com&output=json" \
| jq '.[].not_after' \
| sort -u
CT log monitoring complements direct certificate expiry monitoring — it provides domain-wide visibility without needing to know every hostname in advance.
For context on the broader TLS security picture, including how certificate chains work and why an improperly configured chain causes trust errors even on valid certificates, see our TLS Certificate Chain Validation guide. For hardening your HTTPS configuration beyond certificate validity, see our HTTP Security Headers guide.
Frequently Asked Questions
Q: My certificate shows as valid but users are seeing a security warning — what's happening?
Several possibilities. The most common are: an incomplete certificate chain (the intermediate certificate is missing — browsers can't verify the chain back to a trusted root); the certificate doesn't cover the hostname the user is accessing (a SAN mismatch); or the server is serving an old cached certificate after a renewal. Use the SSL Certificate Checker to inspect the full chain and SAN list, and check our TLS Certificate Chain Validation guide for chain-specific troubleshooting.
Q: How early should I renew my SSL certificate before it expires?
For Let's Encrypt (90-day certificates), certbot and most ACME clients renew automatically at 60 days remaining — 30 days before expiry. For commercial certificates (typically 1-year validity), initiate renewal at 60 days remaining. This gives sufficient buffer to resolve validation failures, rekey if needed, and deploy without time pressure.
Q: Can I use the same SSL certificate for multiple subdomains?
Yes, via two mechanisms. A wildcard certificate (*.example.com) covers all direct subdomains of a domain but not the root domain itself (example.com) or nested subdomains (api.v2.example.com). A multi-SAN certificate lists specific hostnames in the Subject Alternative Names field and covers exactly those names. Both approaches require monitoring to cover all included names — expiry of one certificate takes all of them offline.
Q: Does HTTPS monitoring from an uptime tool replace dedicated certificate expiry monitoring?
Partially. Most uptime monitors check HTTPS reachability and will alert if a site goes down due to an expired cert — but by then the outage has already happened. Dedicated certificate expiry monitoring alerts 30–60 days before expiry, giving you time to renew before any disruption occurs. Both layers are valuable; they serve different purposes.
Q: My Let's Encrypt certificate renewed successfully but the site still shows the old certificate — why?
Certbot renews the certificate but your web server must reload its configuration to pick up the new files. Check whether your certbot installation includes a post-renewal hook that reloads Nginx or Apache. If not, add one: create a file at /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh containing systemctl reload nginx. Many silent renewal failures are actually successful renewals with missing deployment steps.
Q: What's the difference between DV, OV, and EV certificates?
Domain Validation (DV) certificates verify only that the requester controls the domain — the most common type, issued automatically in minutes. Organisation Validation (OV) certificates additionally verify the legal organisation behind the domain. Extended Validation (EV) certificates require rigorous identity verification of the organisation. All three provide the same level of cryptographic protection for the HTTPS connection; they differ only in what has been verified about the certificate holder.
Next Steps
Run an immediate audit using the openssl commands in this guide or the SSL Certificate Checker to get the current expiry date and days-remaining figure for every domain you operate. Add the results to your monitoring inventory and configure alerts at 60-day and 30-day thresholds before closing the audit.
If you find any certificates with chain configuration issues — or if users are reporting trust warnings on domains with technically valid certificates — see our TLS Certificate Chain Validation guide for the diagnosis and fix workflow.
For hardening your HTTPS posture beyond certificate validity, read our HTTP Security Headers guide which covers HSTS, CSP, and the full set of security headers that complete a properly secured HTTPS deployment.
Browse all security guides on DNSnexus for related topics.