Full Diagnostic Tree & Step-by-Step Overview
What specific SSL certificate failure or renewal issue are you experiencing?
- Let's Encrypt / Certbot ACME HTTP-01 challenge failed during renewal execution
- Certificate was successfully renewed on disk, but browsers still show SEC_ERROR_EXPIRED_CERTIFICATE
- ACME DNS-01 challenge failed or CAA record prevents certificate issuance
- Certificate installed, but browsers display 'Untrusted Certificate Authority' or missing chain error
Which error code or status did Certbot return during the HTTP-01 challenge verification?
- Invalid response / 404 Not Found fetching /.well-known/acme-challenge/
- Connection refused or connection timed out during ACME validation callback
Fix ACME HTTP-01 Challenge 404 Errors in Web Server Configuration
Solution:
Root Cause: Web Server Document Root Misconfiguration or URL Rewrite Collision
The ACME validation server requested the challenge file from
http://yourdomain.com/.well-known/acme-challenge/<TOKEN>, but the web server returned a 404 error because the path mapped to an incorrect directory or was intercepted by a URL rewrite rule.
# Step-by-Step Fix:
Verify Webroot Path in Certbot Configuration:Check the webroot path in /etc/letsencrypt/renewal/yourdomain.conf.Ensure the webroot_path directive matches your web server's actual public document root (e.g., /var/www/html).Configure Dedicated Location Block in Nginx:Add an explicit location rule in your Nginx server block to serve ACME challenges cleanly: nginx
location /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
}
Reload Nginx: sudo nginx -t && sudo systemctl reload nginx.Exclude ACME Path from HTTPS Redirects (Apache / Nginx):Ensure HTTP-to-HTTPS redirect rules do not rewrite /.well-known/acme-challenge/ before the file can be read.Test Renewal Manually:Run dry run validation: sudo certbot renew --dry-run.
Fix Inbound Firewall and Port 80 Blockage for ACME Validation
Solution:
Root Cause: Inbound HTTP (Port 80) Traffic Blocked by Network Firewall or Security Group
Let's Encrypt validation servers perform HTTP-01 challenges over plain HTTP (Port 80). If port 80 is blocked by a cloud security group, OS firewall, or router, the validation request times out.
# Step-by-Step Fix:
Open Port 80 in Cloud Security Groups:AWS/GCP/Azure Console -> Security Groups / Firewall Rules.Add Inbound Rule: Protocol TCP, Port 80, Source 0.0.0.0/0.Open Port 80 in Host Local Firewall:Ubuntu/Debian (UFW): sudo ufw allow 80/tcp && sudo ufw reloadRHEL/CentOS (Firewalld): sudo firewall-cmd --permanent --add-service=http && sudo firewall-cmd --reloadTest External Accessibility:Test port 80 reachability from an external machine: curl -I http://yourdomain.com.Trigger Manual Certbot Renewal:Run: sudo certbot renew.
What is the status of the renewed certificate files relative to your web server process?
- Certbot successfully renewed files in /etc/letsencrypt/live/, but the web server was never reloaded
- Web server configuration references legacy or duplicate certificate paths rather than live symlinks
Configure Automating Web Server Reload Post-Hooks in Certbot
Solution:
Root Cause: Web Server Process Running with In-Memory Expired Certificate
Certbot updated the SSL certificate files on disk in /etc/letsencrypt/live/, but Nginx or Apache was not reloaded, leaving the expired certificate active in process memory.
# Step-by-Step Fix:
Manually Reload Web Server Process:Nginx: sudo systemctl reload nginxApache: sudo systemctl reload apache2 (or httpd)Configure Automatic Deploy Hook in Certbot:Open /etc/letsencrypt/renewal/yourdomain.conf and ensure renew_hook is set, or run: sudo certbot renew --deploy-hook "systemctl reload nginx"
Verify Systemd Renewal Timer:Check that the systemd timer is active: sudo systemctl status certbot.timer.Test post-hook execution: sudo certbot renew --dry-run.
Update Web Server VirtualHost to Point to Correct Live Symlinks
Solution:
Root Cause: Web Server Configuration Hardcoded to Static Archival or Old Certificate Files
The web server VirtualHost configuration references hardcoded paths (such as cert1.pem or a custom directory) instead of pointing to the dynamic symlinks inside /etc/letsencrypt/live/yourdomain/.
# Step-by-Step Fix:
Inspect Nginx / Apache SSL Paths:Nginx: Check ssl_certificate and ssl_certificate_key directives in your site config. ssl_certificate /etc/letsencrypt/live/yourdomain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain/privkey.pem;
Apache: Check SSLCertificateFile and SSLCertificateKeyFile directives. SSLCertificateFile /etc/letsencrypt/live/yourdomain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain/privkey.pem
Verify Symlink Integrity:Confirm /etc/letsencrypt/live/yourdomain/fullchain.pem points to the latest file in /etc/letsencrypt/archive/yourdomain/.Reload Web Server:Run sudo nginx -t && sudo systemctl reload nginx.
Which DNS-related issue is preventing automated ACME renewal?
- DNS CAA record explicitly blocks Let's Encrypt or your Certificate Authority
- DNS-01 TXT record API authentication failed or propagation timed out
Update DNS CAA Records to Authorize Certificate Authority
Solution:
Root Cause: DNS CAA (Certification Authority Authorization) Record Restriction
A CAA record exists in your DNS zone file that restricts which CAs are allowed to issue certificates for your domain, but it excludes your chosen CA (e.g., letsencrypt.org).
# Step-by-Step Fix:
Query Existing CAA Records:Run dig command to inspect current CAA records: dig CAA yourdomain.com +short.Add Authorizing CAA Entry in DNS Provider:Log into your DNS provider (Cloudflare, Route53, GoDaddy).Create a new CAA record:Name: @ (or domain apex)Tag: issueValue: letsencrypt.org (or digicert.com, sectigo.com depending on provider)Verify Propagation and Retry:Check propagation: dig CAA yourdomain.com +shortRetry renewal: sudo certbot renew.
Fix DNS-01 API Credentials and Increase Propagation Timeout
Solution:
Root Cause: Invalid DNS API Credentials or Insufficient TXT Record Propagation Time
The ACME client attempted to place an _acme-challenge TXT record via DNS API, but the API token expired, lacked zone edit permissions, or the DNS record did not propagate across global nameservers before validation timed out.
# Step-by-Step Fix:
Verify API Credentials:Open your DNS plugin configuration file (e.g., /etc/letsencrypt/cloudflare.ini).Confirm the API token has Zone.DNS edit permissions for the target domain.Increase Propagation Delay Parameter:Add propagation delay flag to your Certbot command to allow DNS changes to replicate: sudo certbot renew --dns-cloudflare-propagation-seconds 60
Manually Verify TXT Record Creation:Monitor TXT record creation during dry-run: dig TXT _acme-challenge.yourdomain.com +short.
What specific certificate chain validation error is reported by clients or SSL testing tools?
- Missing Intermediate CA Certificate (Web server serves cert.pem instead of fullchain.pem)
- Legacy client OS lacks updated Root CA certificate or system time clock is skewed
Configure Server to Serve Full Certificate Chain (fullchain.pem)
Solution:
Root Cause: Incomplete SSL Certificate Chain (Missing Intermediate CA)
The web server is configured to serve only the leaf certificate (cert.pem) without including the intermediate CA certificate. Browsers that lack cached intermediate certificates reject the connection as untrusted.
# Step-by-Step Fix:
Update Nginx Directive:Replace ssl_certificate /path/to/cert.pem; with ssl_certificate /etc/letsencrypt/live/yourdomain/fullchain.pem;.Update Apache Directive:For Apache 2.4.8+: Set SSLCertificateFile to fullchain.pem.For older Apache versions: Keep SSLCertificateFile pointing to cert.pem and add SSLCertificateChainFile /etc/letsencrypt/live/yourdomain/chain.pem.Test Certificate Chain Integrity:Run OpenSSL verification: openssl s_client -connect yourdomain.com:443 -showcerts.Ensure all certificates in the chain (Leaf -> Intermediate -> Root) are returned.
Synchronize System Clock and Update Host CA Root Store
Solution:
Root Cause: Host System Time Drift or Outdated Root CA Store on Client System
The client or server system clock is out of sync (causing valid certificates to evaluate as not yet valid or already expired), or the client OS lacks modern trust store certificates.
# Step-by-Step Fix:
Synchronize Server System Time via NTP:Check time status: timedatectl status.Force NTP synchronization:Linux: sudo systemctl restart systemd-timesyncd or sudo ntpdate pool.ntp.orgWindows: w32tm /resyncUpdate OS CA Certificates Package:Ubuntu/Debian: sudo apt-get update && sudo apt-get install --reinstall ca-certificatesRHEL/CentOS: sudo yum update ca-certificatesRe-test Connection:Verify connection using curl: curl -vI https://yourdomain.com.