Let’s Encrypt certificate errors on Apache usually appear as browser warnings like “Your connection is not private” or “NET::ERR_CERT_DATE_INVALID”. These errors happen when the certificate is expired, the web server isn’t serving the correct certificate, or the automatic renewal isn’t working. This guide walks you through diagnosing and fixing the most common causes, from checking certificate expiry to reconfiguring virtual hosts and forcing renewal.
What You’ll Need
- SSH (terminal) access to your server with sudo privileges
- Your Apache configuration files located in
/etc/apache2/(Debian/Ubuntu) or/etc/httpd/(RHEL/CentOS) - The Certbot client installed (usually via
certbotpackage) - Your domain name and the path to your web root (e.g.,
/var/www/html)
Step-by-Step
- Identify the exact error. Open your browser’s error page and click “Advanced” or “More information”. Note the error code (e.g.,
SEC_ERROR_EXPIRED_CERTIFICATE,SSL_ERROR_BAD_CERT_DOMAIN). This tells you whether the problem is expiry, domain mismatch, or something else. - Check certificate expiry. Run
sudo certbot certificatesto list all certificates managed by Certbot. Look for theExpiry Dateof your domain. If it’s in the past, the certificate is expired and needs renewal. - Test the renewal process. Run
sudo certbot renew --dry-run. This simulates renewal without actually changing anything. If it fails, you’ll see the error (often a DNS issue or port 80 blocked). Fix that first before proceeding. - Force renewal if needed. If the certificate is expired or the dry run succeeds but the real renewal didn’t happen, run
sudo certbot renew --force-renewal. This will obtain a new certificate and automatically reload Apache if the Certbot Apache plugin is installed. - Verify the certificate is being served. After renewal, check which certificate Apache is actually using:
sudo openssl s_client -connect yourdomain.com:443 -servername yourdomain.com(replace yourdomain.com). Look for thesubjectandissuerlines. The issuer should beR3or similar Let’s Encrypt root. If it’s a self-signed or old certificate, Apache is pointing to the wrong file. - Check Apache virtual host configuration. Open your site’s SSL config file (e.g.,
/etc/apache2/sites-available/yourdomain-le-ssl.conf). Ensure theSSLCertificateFileandSSLCertificateKeyFilepaths match the ones shown insudo certbot certificates(usually under/etc/letsencrypt/live/yourdomain/). Also verify thatSSLCertificateChainFileorSSLCACertificateFilepoints tochain.pemorfullchain.pem. - Test Apache configuration. Run
sudo apachectl configtest(orsudo httpd -ton RHEL). Fix any syntax errors it reports. Then reload Apache:sudo systemctl reload apache2(orsudo systemctl reload httpd). - Check port 80 is open. Let’s Encrypt HTTP-01 challenge requires port 80 to be reachable from the internet. Use
sudo netstat -tulpn | grep :80to see if Apache is listening. If a firewall blocks it, open port 80 (and 443) in your firewall settings. - Verify renewal timer. Ensure the systemd timer for Certbot is enabled:
sudo systemctl list-timers | grep certbot. If it’s not there, enable it withsudo systemctl enable --now certbot.timer(Debian/Ubuntu) or set up a cron job. - Test the site in a browser. After all fixes, clear your browser cache or use an incognito window to visit your domain. The padlock should appear. Use an online SSL checker (like SSL Labs) to confirm the certificate chain is valid.
Common Mistakes
- Forgetting to renew before expiry. Let’s Encrypt certificates last 90 days. If your renewal cron/timer isn’t running, you’ll hit expiry. Always test the renewal process after setup.
- Wrong file paths in Apache config. Copy-pasting config from a tutorial but not updating the domain name in the
SSLCertificateFilepaths is a classic error. Always use the exact paths fromcertbot certificates. - Blocking port 80. Many firewalls only allow 443. The HTTP-01 challenge needs port 80 open, even if you redirect all HTTP to HTTPS. If port 80 is blocked, renewal fails silently.
- Editing the wrong virtual host. Apache may load a default SSL config that overrides yours. Use
sudo apachectl -Sto see which virtual hosts are actually loaded and on which ports. - Not reloading Apache after renewal. Certbot usually reloads Apache automatically, but if you manually renew or change config, you must reload Apache to apply the new certificate.
Tips
- Set up a cron job to renew certificates twice a day:
0 0,12 * * * certbot renew --quiet. This ensures you never miss the 90-day window. - Use the Certbot Apache plugin (
sudo certbot --apache) to automatically configure virtual hosts and handle renewals. It’s less error-prone than manual config. - Keep a backup of your Apache config before making changes:
sudo cp /etc/apache2/sites-available/yourdomain-le-ssl.conf /etc/apache2/sites-available/yourdomain-le-ssl.conf.bak. - Monitor your certificate expiry with a service like UptimeRobot or a simple script that checks
openssl s_clientand alerts you a week before expiry. - If you use a CDN (like Cloudflare), ensure the SSL mode is set to “Full (strict)” so the CDN trusts your Let’s Encrypt certificate.
Troubleshooting
Renewal fails with “Failed to connect to host for DVSNI challenge”. This usually means port 80 is blocked or Apache isn’t listening. Check your firewall and that Apache is running. Also verify DNS resolves to your server’s IP.
Certificate renews but browser still shows error. Your browser may have cached the old certificate. Try a different browser or clear the SSL cache. Also check if you have multiple certificates for the same domain; Certbot may be renewing the wrong one.
Apache won’t start after config change. Run sudo apachectl configtest to see the exact syntax error. Common issues: missing closing tag, wrong path, or a typo in the certificate file name.
Certificate is valid but shows “Not Secure” for subdomains. Ensure your certificate covers all subdomains you use. If not, run sudo certbot --apache -d example.com -d www.example.com to expand the certificate.
Certbot says “No renewals were attempted” and exits. This means the certificate is not yet due for renewal. Check the expiry date; if it’s more than 30 days away, you can force renewal with --force-renewal.
Error “Certbot doesn’t know how to automatically configure the web server”. This happens when the Apache plugin is missing. Install it with sudo apt install python3-certbot-apache (Debian/Ubuntu) or sudo yum install python3-certbot-apache (RHEL).
Frequently Asked Questions
Q: How often do Let’s Encrypt certificates expire?
A: Every 90 days. You must renew before that, and automatic renewal is essential.
Q: What is the difference between fullchain.pem and cert.pem?
A: cert.pem is just your certificate; fullchain.pem includes the intermediate certificates. Apache should use fullchain.pem to ensure browsers trust the chain.
Q: Can I use the same certificate for multiple domains?
A: Yes, use a SAN certificate by specifying multiple -d flags when issuing. For example: sudo certbot --apache -d example.com -d www.example.com -d api.example.com.
Q: Why does my certificate show as “self-signed” in the browser?
A: This usually means Apache is pointing to a self-signed certificate file instead of the Let’s Encrypt one. Check the SSLCertificateFile path in your virtual host.
Q: What if I can’t access port 80 from the internet?
A: You can use the DNS-01 challenge instead of HTTP-01. Run sudo certbot --apache --preferred-challenges dns and follow the prompts to add a TXT record to your DNS.
Q: How do I check if my certificate is installed correctly?
A: Use an online SSL checker or run openssl s_client -connect yourdomain.com:443 -servername yourdomain.com and look for the issuer and validity dates.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- China’s IPv9 Decimal Network Project Explained
- Fix Wired Earbuds That Only Work in One Ear
- What to Check Before Buying the Dip in Indian Shares
- Cool Raspberry Pi Projects: 15 Ideas for Any Skill Level3
- Terraform vs Kubernetes: Key Differences
- Internet Connectivity in Remote Areas: Options0.80 USD/GB