A failed certificate renewal can leave an otherwise healthy website showing a browser security warning. If Certbot renewal failed on Ubuntu with Nginx, start by identifying the affected certificate and the exact validation error. Then check DNS, challenge access, the renewal job, and the certificate Nginx actually serves.
This guide is for an Ubuntu VPS with an existing Certbot-managed certificate and Nginx running as a system service. Replace example.com with your domain. If a hosting panel owns your certificates, use its supported renewal workflow first; a second ACME client can create conflicting configuration.
Quick diagnosis: where is renewal failing?
Separate the problem into three stages: the renewal job must run, domain validation must succeed, and the renewed certificate must reach the HTTPS endpoint. Use the symptom to choose your first check.
| Symptom | First check |
|---|---|
| No recent renewal attempts | The installed timer or cron job and its last execution. |
| Connection timeout during HTTP validation | DNS destination, port 80, firewall rules, and public reachability. |
| Unauthorized response or challenge 404 | The requested hostname, challenge routing, and webroot. |
| Validation works over IPv4 only | The domain's AAAA record and IPv6 server configuration. |
| Renewal succeeds but browsers see an old certificate | Nginx certificate paths, reload status, and any CDN or load balancer. |
1. Identify the certificate and reproduce the error
List the certificates, then test only the affected one. Use the exact certificate name shown in the output; it may include a suffix such as -0001.
sudo certbot certificates
sudo certbot renew --cert-name example.com --dry-run
sudo tail -n 100 /var/log/letsencrypt/letsencrypt.log
The dry run normally uses Let's Encrypt's staging service and does not replace the live certificate. Review existing renewal hooks first: pre- and post-hooks can still run, including scripts that stop services. See the Certbot renewal guide.
Record the failing hostname, challenge type, and response. A certificate covering both the root domain and www needs working validation for every included name. Fix the reported failure before repeating the test.
2. Check public DNS, including IPv6
Compare the public addresses with the server or proxy that should answer for your domain. If dig is available, run:
dig +short A example.com
dig +short AAAA example.com
dig +short A www.example.com
dig +short AAAA www.example.com
An unexpected address is a useful lead after a VPS migration or DNS change. If your domain is intentionally behind a proxy, its public addresses may differ from the origin; trace how that proxy forwards validation requests.
Let's Encrypt initially prefers IPv6 when both A and AAAA records exist. An IPv6 server returning the wrong challenge response does not trigger an IPv4 retry. Correct a stale AAAA record, or remove it if you do not intend to provide IPv6 service. This behavior is described in Let's Encrypt's IPv6 documentation.
Recheck DNS after the change has propagated. A successful test from your own VPS alone does not prove that outside clients reach the same destination.
3. Check HTTP-01 access and challenge routing
HTTP-01 validation begins on port 80. It cannot start on an arbitrary alternative port, and it cannot issue wildcard certificates. DNS-01 is the appropriate challenge for wildcard names. See the official challenge types reference.
On the VPS, inspect listeners and, if your server uses UFW, its rules:
sudo ss -ltnp
sudo ufw status verbose
Look for Nginx listening on port 80. Also inspect the VPS provider's firewall or security group. A local listener cannot establish whether upstream filtering permits incoming traffic.
From another machine, make a normal HTTP request:
curl -I http://example.com/
A response confirms basic connectivity, but does not prove the challenge path works. An HTTP-to-HTTPS redirect is not automatically a problem; Let's Encrypt supports certain redirects. Check the actual challenge URL and error rather than removing every redirect. Its port 80 guidance explains the usual HTTP and HTTPS setup.
For a challenge 404, inspect the matching server block and webroot. For a 403 or login page, inspect access restrictions, proxy rules, and authentication applied to /.well-known/acme-challenge/. Test every frontend if requests can reach more than one server.
When a webroot directory has moved, Certbot 2.3 or newer supports a tested configuration update. Replace the sample path with the directory that serves this domain:
sudo certbot reconfigure --cert-name example.com --webroot-path /var/www/example/public
Use this only for an existing webroot setup. Follow the renewal configuration documentation when changing plugins or other options.
4. Confirm automatic renewal actually runs
A successful interactive test does not establish that unattended renewal is working. Inspect the installed timers:
systemctl list-timers --all
Find the Certbot-related entry and note its next run, last run, and activated service. Names vary by installation method. Inspect the service shown in that output, replacing this example name if necessary:
sudo systemctl status certbot.service --no-pager
sudo journalctl -u certbot.service --since "7 days ago" --no-pager
If no timer exists, check whether your installation uses cron. Consult the official instructions for your installation method before adding a job. Avoid accumulating duplicate schedules while the original failure remains unexplained.
For a missing executable or plugin error, compare the command path used by the job with the installation you tested interactively. An old job can outlive a change from one packaging method to another.
5. Check what Nginx and visitors actually see
If renewal succeeded, inspect Nginx before requesting another certificate:
sudo nginx -t
sudo nginx -T
The -t option tests configuration and referenced files; -T also prints the configuration. Review the affected domain's server_name, ssl_certificate, and ssl_certificate_key paths. Keep configuration output private if it contains credentials. These options are documented in the Nginx command reference.
After confirming the paths and a successful configuration test, reload the service:
sudo nginx -t && sudo systemctl reload nginx
Nginx applies configuration changes on reload while allowing existing workers to finish their requests. See its process control guide. If the test fails, repair the reported issue before reloading.
Inspect the leaf certificate returned by the public HTTPS endpoint:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
This command displays certificate details; it is not a complete trust or hostname verification. The OpenSSL client reference explains the connection and server-name options, and the certificate reference covers the displayed fields.
If a CDN or load balancer terminates HTTPS, the public command shows that endpoint's certificate. Check its certificate lifecycle separately from the origin. For multiple HTTPS frontends, verify each one.
6. Close the gap between renewal and deployment
For a manually managed certonly setup, confirm there is a persistent deployment step that reloads the consuming service after successful renewal. Use a deploy hook where appropriate. Certbot does not run deploy hooks during a dry run unless --run-deploy-hooks is requested. Review the hook's effects before testing it.
Before closing the incident, confirm:
- The affected certificate passes its renewal test.
- The unattended job has a valid schedule and useful logs.
- Every HTTPS endpoint presents the intended certificate.
- An external expiry alert reaches someone who can act.
- The fix and responsible owner are recorded for the next server change.
Frequently asked questions
Should I keep forcing renewal until it works?
No. First resolve the validation or deployment error, then repeat a staging test. Use a normal live renewal when the certificate is due. Reissuing a certificate cannot repair incorrect DNS or a frontend serving the wrong file.
Does a successful dry run mean my live certificate has renewed?
No. Treat it as a test of the renewal path. Check the live certificate's expiry and the certificate presented to visitors separately.
What if HTTPS works but the website returns 502?
That points to another layer of the request. Continue with our guide to fixing Nginx 502 Bad Gateway errors on Ubuntu and inspect the application upstream.
Make certificate checks part of VPS operations
Retest renewal after changing DNS, firewall rules, webroots, proxies, or hosting software. Add these checks to your VPS security baseline so certificate ownership stays clear as your hosting setup grows.
If you are evaluating a VPS control panel, include certificate renewal, deployment, and failure visibility in your evaluation. Review the Core Panel documentation and validate the workflow on an isolated non-production server; Core Panel is currently classified as pre-production.



