SSL Certificate Renewal: Complete Guide (Avoid Downtime)
An expired SSL certificate causes an immediate, visible outage - browsers block users with a full-page warning, APIs refuse to connect, and SEO rankings drop. Yet certificate expiry is entirely preventable with a proper renewal and monitoring strategy. This guide covers everything from checking expiry dates to emergency recovery.
The Problem: Why Certificates Expire Unexpectedly
Modern SSL/TLS certificates from Let's Encrypt have a 90-day validity period. Commercial certificates from DigiCert, Sectigo, and others typically run for 1-2 years (the CA/Browser Forum capped new certificates at 398 days in 2020). Despite these well known validity windows, certificate expiry remains one of the most common causes of web outages.
The reasons vary: the engineer who originally set up the certificate has left the company and nobody else knows where it lives; the renewal reminder emails go to a generic inbox that nobody monitors; the auto-renewal cron job silently failed months ago; or the certificate was manually installed on a load balancer that was later rebuilt. In every case, the result is the same: a jarring warning page that drives users away and triggers incident alerts.
In 2020, a major US government agency's COVID-19 response website went down for hours due to an expired certificate. In 2023, Microsoft Teams experienced a global outage partly attributed to certificate mismanagement. Certificate expiry causes real, costly incidents at organisations of every size.
Step 1: Check Your Current Certificate Expiry
Before setting up automation, audit what you have. There are several ways to check a certificate's expiry date:
From the Command Line (openssl)
# Check expiry for any 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 2026 GMT
# notAfter=May 30 00:00:00 2026 GMT
# Check days remaining (Linux/macOS)
expiry=$(echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
days=$(( ($(date -d "$expiry" +%s) - $(date +%s)) / 86400 ))
echo "Certificate expires in $days days"
Check a Local Certificate File
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -dates
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -subject -issuer -dates
Check All Let's Encrypt Certificates
sudo certbot certificates
# Lists all managed certificates, their domains, expiry dates, and certificate paths
Check Any Domain's SSL Certificate
Instantly inspect certificate expiry, issuer, TLS version, cipher suite, and HSTS headers for any domain. Free, no account needed.
Open SSL CheckerStep 2: Set Up Automated Renewal with Certbot
Let's Encrypt certificates are free and renew automatically with Certbot. If you are not already using Let's Encrypt, start here. If you are using a commercial CA, skip to the monitoring section.
Install Certbot
# Ubuntu/Debian
sudo apt update && sudo apt install certbot python3-certbot-nginx
# CentOS/RHEL
sudo dnf install certbot python3-certbot-nginx
# macOS (via Homebrew)
brew install certbot
Issue Your First Certificate (Nginx)
# Certbot automatically configures Nginx
sudo certbot --nginx -d example.com -d www.example.com
# Or obtain only (configure Nginx manually)
sudo certbot certonly --nginx -d example.com -d www.example.com
Test Auto-Renewal
# Dry run - simulates renewal without making changes
sudo certbot renew --dry-run
# If successful, you see:
# Congratulations, all simulated renewals succeeded
Verify the Auto-Renewal Timer
Certbot installs a systemd timer (or cron job) that runs twice daily. Verify it is active:
# Check systemd timer status
sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbot
# Enable if not already enabled
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
# On older systems using cron
cat /etc/cron.d/certbot
# Should contain something like:
# 0 */12 * * * root certbot renew --quiet
Post-Renewal Hook (Reload Web Server)
Certbot can automatically reload Nginx or Apache after renewal so the new certificate is picked up without manual intervention:
# Create a post-renewal hook
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
Step 3: Wildcard Certificate Renewal (DNS Challenge)
Wildcard certificates (e.g., *.example.com) cover all subdomains but require DNS-01 challenge validation - you cannot use the HTTP-01 challenge. This means your DNS provider must support API-based record creation.
# Install the DNS plugin for your provider (example: Cloudflare)
sudo pip3 install certbot-dns-cloudflare
# Create Cloudflare credentials file
sudo nano /etc/letsencrypt/cloudflare.ini
# dns_cloudflare_api_token = your_api_token_here
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
# Issue wildcard certificate
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d example.com \
-d "*.example.com"
# Renewal is automatic via the same credentials
DNS plugin packages exist for Route53 (certbot-dns-route53), Google Cloud DNS (certbot-dns-google), DigitalOcean (certbot-dns-digitalocean), and most major providers.
Step 4: Monitoring and Alerting Before Expiry
Automation can fail silently. Always add independent monitoring as a safety net.
Bash Script with Email Alert
#!/bin/bash
# ssl-monitor.sh - alert if certificate expires within 30 days
DOMAIN="example.com"
THRESHOLD=30
ALERT_EMAIL="ops@example.com"
expiry=$(echo | openssl s_client -connect $DOMAIN:443 -servername $DOMAIN 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
days=$(( ($(date -d "$expiry" +%s) - $(date +%s)) / 86400 ))
if [ $days -lt $THRESHOLD ]; then
echo "WARNING: $DOMAIN certificate expires in $days days ($expiry)" \
| mail -s "SSL EXPIRY ALERT: $DOMAIN" $ALERT_EMAIL
echo "Alert sent for $DOMAIN ($days days remaining)"
fi
# Add to crontab - run daily at 08:00
0 8 * * * /usr/local/bin/ssl-monitor.sh >> /var/log/ssl-monitor.log 2>&1
Using External Monitoring Services
- Uptime Robot (free) - monitors SSL expiry with 30-day email alerts
- StatusCake (free tier) - SSL monitoring with Slack/PagerDuty integration
- Datadog - built-in SSL check with configurable alert thresholds
- Grafana + Blackbox Exporter - self-hosted, Prometheus-based SSL monitoring
- AWS Certificate Manager - auto-renews ACM certificates, sends CloudWatch events 45 and 30 days before expiry
Prometheus + Alertmanager Rule
# prometheus-rules.yml
groups:
- name: ssl
rules:
- alert: SSLCertExpiringSoon
expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30
for: 1h
labels:
severity: warning
annotations:
summary: "SSL certificate expiring soon for {{ $labels.instance }}"
description: "Certificate expires in {{ $value | humanizeDuration }}"
Step 5: Commercial Certificate Renewal (Manual Process)
For OV (Organisation Validated) or EV (Extended Validation) certificates from commercial CAs, renewal involves human verification and cannot be fully automated. The process:
- Generate a new CSR (Certificate Signing Request) from your server:
# Generate a new private key and CSR
openssl req -new -newkey rsa:2048 -nodes \
-keyout example.com.key \
-out example.com.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Example Inc/CN=example.com"
# View the CSR to confirm contents
openssl req -in example.com.csr -noout -text
- Submit the CSR to your CA (DigiCert, Sectigo, etc.) via their web portal
- Complete domain validation (email, DNS record, or HTTP file challenge)
- For OV/EV: complete organisation verification (may take 1-3 business days)
- Download the new certificate bundle from the CA portal
- Install on your server and reload the web server
Start commercial certificate renewal at least 30 days before expiry to account for OV/EV verification time. Calendar reminders are unreliable - use external monitoring tools as your primary early-warning system.
Emergency Recovery: Certificate Already Expired
If you discover your certificate has already expired and your site is showing a browser warning, act immediately:
# Option 1: Force immediate Certbot renewal (if using Let's Encrypt)
sudo certbot renew --force-renewal
sudo systemctl reload nginx
# Option 2: Issue a brand new certificate if the old one can't be renewed
sudo certbot --nginx -d example.com -d www.example.com
sudo systemctl reload nginx
# Verify the new certificate is live
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
If users are blocked by browser warnings, they may not be able to reach your site at all. Keep an out-of-band communication channel (status page on a separate domain, Slack, email) ready to notify users during recovery.
Certificate Pinning: When It Complicates Renewal
Some mobile apps implement certificate pinning - hardcoding the expected certificate fingerprint into the app binary. If you renew your certificate (which changes the fingerprint), pinned clients will refuse to connect until users update the app. Consider pinning to the CA intermediate certificate or the public key hash (HPKP) rather than the leaf certificate, or avoid pinning altogether for public APIs where renewal agility is more important than the added security.
Frequently Asked Questions
How often does Certbot try to renew certificates?
The Certbot timer runs twice daily. However, it only actually renews a certificate when it is within 30 days of expiry (for Let's Encrypt certificates). Let's Encrypt's 90-day validity plus 30-day renewal window means you always have a substantial buffer. You can confirm by running sudo certbot renew --dry-run and checking the output.
Can I renew a certificate before it expires?
Yes. You can force early renewal with certbot renew --force-renewal or certbot certonly --force-renew. This is useful when you need to add a new subdomain to an existing certificate or after rotating your private key following a security incident. Let's Encrypt enforces rate limits (5 certificates per domain per week), so avoid unnecessary forced renewals.
What happens to existing connections when the certificate is renewed?
Nothing - until the web server reloads. Active connections continue with the old certificate until they close naturally. After systemctl reload nginx (or Apache), new connections use the new certificate. The reload itself is graceful and does not drop existing connections. The transition is invisible to users.
My site is behind a CDN (Cloudflare, CloudFront). Do I still need to renew?
For traffic served by the CDN, the CDN's own certificate is what users see, and major CDNs manage their certificates automatically. However, the origin certificate - the one between your CDN and your server - still needs to be renewed. Cloudflare Origin Certificates are valid for up to 15 years; AWS ACM certificates auto-renew. Check your specific CDN's documentation to confirm what requires manual action.
What is ACME and how does it relate to Let's Encrypt and Certbot?
ACME (Automatic Certificate Management Environment) is the protocol (RFC 8555) that Let's Encrypt uses for automated certificate issuance and renewal. Certbot is a client that implements the ACME protocol. Other ACME clients include acme.sh (shell script, popular for its flexibility), Caddy (built-in ACME, zero-config HTTPS), Traefik (automatic HTTPS for containerised services), and cert-manager (Kubernetes-native ACME client). Any ACME-compatible CA can be used, not just Let's Encrypt.
The Bottom Line
SSL certificate renewal is a solved problem. Let's Encrypt and Certbot handle the renewal cycle fully automatically for most setups, with minimal configuration. For commercial certificates, external monitoring services provide the 30-60 day warning window you need to complete manual renewal before users are affected. The only unacceptable approach is relying on calendar reminders or manual checks - those always fail eventually.
Start by auditing your current certificates today: Use our SSL Checker tool here →
Usman has 10+ years of experience securing enterprise infrastructure, managing high-traffic servers, and building zero-knowledge security tools. Read more about the author.