Troubleshooting Let’s Encrypt Renewal Error: ‘Too Many Certificates for Domain’ on Ubuntu 22.04 LTS
Resolve 'Too Many Certificates' Let's Encrypt renewal errors on Ubuntu 22.04 LTS. This guide helps clear excess certs and restore automatic SSL renewals.
Resolve 'Too Many Certificates' Let's Encrypt renewal errors on Ubuntu 22.04 LTS. This guide helps clear excess certs and restore automatic SSL renewals.
Facing the "Too Many Certificates for Domain" error during a Let's Encrypt renewal can be frustrating, especially when it leaves your website serving an expired or insecure connection. This issue typically arises when numerous certificates have been issued for the same domain within a short period, exceeding Let's Encrypt's established rate limits. As an expert Systems Administrator, I'll guide you through diagnosing the root cause, identifying redundant certificates, safely removing them, and ultimately getting your SSL renewals back on track on your Ubuntu 22.04 LTS server.
Symptom & Error Signature
When attempting to renew your Let's Encrypt certificates, either manually via certbot renew or during an automated cron job, the process fails. Your website might display an "NET::ERR_CERT_DATE_INVALID" or "Your connection is not private" error in web browsers if the existing certificate has expired.
The most common error messages you'll encounter in your terminal or /var/log/letsencrypt/letsencrypt.log will resemble the following:
$ sudo certbot renew --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but trying anyway.
Plugins selected: Authenticator nginx, Installer nginx
Attempting to renew cert (example.com) from /etc/letsencrypt/renewal/example.com.conf produced an unexpected error: An error occurred while communicating with the Let's Encrypt ACMEv2 API. (Detail: urn:ietf:params:acme:error:rateLimited :: Rate limit for 'certificates per Registered Domain' exceeded.). Skipping.
All renewals failed. The following certs could not be renewed:
/etc/letsencrypt/live/example.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)
Ask for help or search for solutions at https://community.letsencrypt.org/.
See the logfile /var/log/letsencrypt/letsencrypt.log for more details.
The key phrase here is Rate limit for 'certificates per Registered Domain' exceeded.
Root Cause Analysis
The "Too Many Certificates for Domain" error is a direct consequence of hitting a specific Let's Encrypt rate limit: Certificates per Registered Domain.
Let's Encrypt imposes rate limits to ensure fair usage and prevent abuse of their free certificate service. The most relevant limit in this scenario is:
- Certificates per Registered Domain: You can issue a maximum of 50 certificates for a given Registered Domain within a rolling 7-day window. A Registered Domain is typically the main domain name (e.g.,
example.com), and all its subdomains (e.g.,www.example.com,blog.example.com,app.example.com) count towards this limit for that Registered Domain.
Why does this limit often get hit?
- Repeated
certbot certonlyorcertbot runattempts: Ifcertbotis invoked withcertonlyorruncommands (instead ofrenew) for the same set of domains, it attempts to issue a new certificate each time. This often happens if users don't understandcertbot's workflow or if automated scripts fail and retry frequently without checking for existing certificates. - Misconfigured Automation: Automated scripts or cron jobs might be issuing new certificates rather than renewing existing ones, especially if they operate on a per-subdomain basis instead of managing a consolidated certificate.
- Testing with Real Certificates: Using
certbot certonlyrepeatedly for testing purposes without utilizing--dry-runcan quickly consume your quota. - Dynamic Subdomains & Poor Management: If you frequently add or remove subdomains and issue separate certificates for each change, rather than managing a single certificate that covers all necessary (and stable) subdomains, you can hit the limit.
- Incorrect
certbotState: Sometimes,certbot's internal configuration (in/etc/letsencrypt) can become corrupted or inconsistent, leading it to believe no certificate exists and thus attempting to issue a new one instead of renewing.
Understanding this limit is crucial. The solution involves cleaning up the redundant certificates and ensuring certbot is configured to renew existing certificates correctly.
Step-by-Step Resolution
The goal is to identify and remove the excess certificates from your certbot installation, wait for the rate limit to clear, and then successfully renew or issue a single, consolidated certificate.
1. Assess Existing Certificates
First, list all certificates certbot knows about. This helps identify duplicates or unnecessary entries.
sudo certbot certificates
Look for certificates associated with your problem domain. You might see multiple entries for the same domain or subdomains.
Example Output:
Found the following certs:
Certificate Name: example.com-0001
Domains: example.com www.example.com
Expiry Date: 2026-03-20 10:30:00+00:00 (VALID: 80 days)
Certificate Path: /etc/letsencrypt/live/example.com-0001/fullchain.pem
Certificate Name: example.com
Domains: example.com www.example.com
Expiry Date: 2026-03-20 10:30:00+00:00 (VALID: 80 days)
Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
Certificate Name: old.example.com
Domains: old.example.com
Expiry Date: 2026-01-15 05:00:00+00:00 (VALID: 10 days)
Certificate Path: /etc/letsencrypt/live/old.example.com/fullchain.pem
In this example, example.com and example.com-0001 might be duplicates. If old.example.com is no longer needed, it should also be removed.
2. Identify and Backup Certbot Configuration
Before making any changes, it's critical to back up your entire /etc/letsencrypt directory. This allows you to revert if anything goes wrong.
sudo tar -czvf /root/letsencrypt_backup_$(date +%F_%H-%M-%S).tar.gz /etc/letsencrypt
Store this backup securely. It contains your private keys and certificate configurations.
3. Delete Redundant Certificates
Carefully identify the certificates you no longer need or are duplicates. Use the Certificate Name from the certbot certificates output.
sudo certbot delete --cert-name example.com-0001
sudo certbot delete --cert-name old.example.com
You will be prompted to confirm the deletion.
Deleting the wrong certificate will immediately break HTTPS for the associated domains. Ensure you are deleting redundant or unused certificates only. If in doubt, only delete certificates with very short remaining validity or those you know for certain are duplicates.
Repeat the sudo certbot delete --cert-name <CERT_NAME> command for all superfluous certificates.
After deletion, run sudo certbot certificates again to verify that only the desired certificates remain.
4. Clean Up /etc/letsencrypt/live and /etc/letsencrypt/archive (If certbot delete Fails)
In rare cases, certbot delete might fail or leave remnants. This step is a more advanced, manual cleanup and should only be performed if the previous step did not resolve the issue.
Manual deletion within
/etc/letsencryptcan lead to an unrecoverablecertbotstate if not done correctly. Proceed with extreme caution and ensure you have a fresh backup (from step 2).
Inspect
liveandarchivedirectories:ls -l /etc/letsencrypt/live/ ls -l /etc/letsencrypt/archive/You might see directories corresponding to the certificates you intended to delete.
Manually Remove/Rename: If you find directories like
example.com-0001in/etc/letsencrypt/live/or/etc/letsencrypt/archive/aftercertbot delete, you can move them out of the way.sudo mv /etc/letsencrypt/live/example.com-0001 /etc/letsencrypt/live/example.com-0001.bak sudo mv /etc/letsencrypt/archive/example.com-0001 /etc/letsencrypt/archive/example.com-0001.bakAlso, check for and remove the corresponding renewal configuration file:
sudo rm /etc/letsencrypt/renewal/example.com-0001.confAfter these manual steps, run
sudo certbot certificatesagain to see if the internal state has updated. If not, a fullcertbotreinstall or more drastic manual cleanup might be required (which is beyond the scope of a typical resolution for this specific error).
5. Verify Nginx Configuration
Ensure your Nginx server block points to the correct (the one you intend to keep and renew) certificate paths. Typically, this would be /etc/letsencrypt/live/your.domain.name/fullchain.pem and privkey.pem.
Examine your Nginx configuration files, usually located in /etc/nginx/sites-available/:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# ... other SSL directives ...
}
Test your Nginx configuration for syntax errors:
sudo nginx -t
If there are no errors, reload Nginx:
sudo systemctl reload nginx
6. Attempt Certificate Renewal/Issuance
After cleaning up the excess certificates, you need to wait for the Let's Encrypt rate limit to reset. This can be anywhere from a few minutes to up to 7 days, depending on how many certificates were issued recently and when the rolling window expires. Typically, if you've only hit the limit once, a few hours might suffice.
Once you believe the rate limit has reset, proceed with renewing your desired certificate.
Always use
--dry-runfirst to test the process without hitting real rate limits.
If you have an existing certificate you want to renew (which should be the case after cleanup):
sudo certbot renew --dry-run
If the dry run is successful, proceed with the actual renewal:
sudo certbot renew --force-renewal
--force-renewal tells certbot to attempt renewal even if it thinks the certificate isn't due. Use this sparingly, usually only when recovering from rate limit issues.
If you deleted all certificates for a domain and need to issue a fresh one (less common in this scenario but possible):
sudo certbot --nginx -d example.com -d www.example.com --dry-run
Replace example.com and www.example.com with your actual domain(s). If the dry run is successful, remove --dry-run:
sudo certbot --nginx -d example.com -d www.example.com
After a successful issuance or renewal, certbot will usually handle reloading Nginx. If not, or if you want to be certain:
sudo systemctl reload nginx
Verify your certificate is now valid by checking your website in a browser or using an online SSL checker.
7. Prevent Future Occurrences
To avoid hitting this rate limit again:
- Always use
certbot renew: This command is designed to renew existing certificates. Only usecertbot certonlyorcertbot runwhen you are issuing a brand-new certificate for a domain that doesn't have one managed bycertboton that server. - Consolidate Domains: Whenever possible, issue a single certificate that covers all necessary subdomains (e.g.,
example.com,www.example.com,mail.example.com) rather than separate certificates for each. This is done by adding multiple-dflags to yourcertbotcommand:certbot --nginx -d example.com -d www.example.com -d mail.example.com. - Understand
certbotConfiguration: Get familiar with the files in/etc/letsencrypt/live,/etc/letsencrypt/archive, and/etc/letsencrypt/renewalto understand howcertbotmanages your certificates. - Utilize
--dry-runfor Testing: When experimenting with newcertbotcommands or configurations, always use--dry-runfirst to prevent hitting rate limits unnecessarily. - Review Automation: If you have custom scripts for certificate management, ensure they correctly use
certbot renewand handle existing certificates gracefully.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.