SSL & Certs Advanced

Let’s Encrypt Renewal Error: Too Many Certificates for Domain on CentOS Stream / Rocky Linux (Nginx)

Resolve 'too many certificates for domain' errors during Let's Encrypt renewals on CentOS Stream or Rocky Linux with Nginx. Understand rate limits, clean up old certificates, and correct Certbot configurations.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve 'too many certificates for domain' errors during Let's Encrypt renewals on CentOS Stream or Rocky Linux with Nginx. Understand rate limits, clean up old certificates, and correct Certbot configurations.

Introduction

Encountering a "too many certificates for domain" error during your Let's Encrypt certificate renewal process can be a frustrating experience. It typically means you've hit one of Let's Encrypt's strict rate limits, preventing further certificate issuance for your domain within a specific timeframe. This guide will walk you through diagnosing the root cause on CentOS Stream or Rocky Linux systems running Nginx, cleaning up your certificate environment, and configuring Certbot correctly to prevent future occurrences.

Symptom & Error Signature

When attempting to renew your Let's Encrypt certificates, typically via certbot renew or a systemd timer/cron job, you will observe an error message similar to the following in your terminal output or Let's Encrypt logs (/var/log/letsencrypt/letsencrypt.log):

# Example output from 'sudo certbot renew'
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certificate is due for renewal, but an existing certificate has a newer expiry date than the one Certbot would issue.
(You can use --force-renewal to override this, but that's not recommended without good reason.)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/sub.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
  Domain: sub.example.com
  Type:   urn:ietf:params:acme:error:rateLimited
  Detail: Error creating new order :: too many certificates already issued for a given domain: sub.example.com: see https://letsencrypt.org/docs/rate-limits/

Hint: The Certificate Authority failed to verify the challenge for sub.example.com.
...
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (failure)
  /etc/letsencrypt/live/sub.example.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 renew failures, 0 successes

The key message to identify is too many certificates already issued for a given domain often accompanied by urn:ietf:params:acme:error:rateLimited.

Root Cause Analysis

This error stems directly from Let's Encrypt's rate limits, which are in place to ensure fair usage and prevent abuse of their service. The most common rate limit hit in this scenario is Certificates per Registered Domain.

Let's Encrypt allows a maximum of 50 certificates per Registered Domain per week. A "Registered Domain" is the top-level domain plus one level (e.g., example.com is the Registered Domain for www.example.com, blog.example.com, mail.example.com).

The underlying reasons for hitting this limit typically include:

  1. Repeated New Certificate Issuance Instead of Renewal: The most common culprit. Instead of running certbot renew, which intelligently checks for existing certificates and attempts to renew them, administrators might repeatedly execute commands like certbot certonly -d example.com -d www.example.com or certbot run without proper checks. Each such command (if successful) issues a new certificate, quickly consuming the rate limit.
  2. Frequent Deletion of /etc/letsencrypt/: If the /etc/letsencrypt/ directory (which stores Certbot's configuration, accounts, and existing certificates) is frequently deleted or lost, Certbot loses track of issued certificates and will attempt to issue new ones.
  3. Misconfigured Automation: A script or cron job might be incorrectly configured to always request a new certificate, or run certbot --force-renewal without proper conditional logic, leading to unnecessary re-issuance.
  4. Excessive Testing in Production: Using live domains for frequent testing of Certbot commands instead of the --dry-run option or Let's Encrypt's staging environment.
  5. Too Many Unique Subdomains on Separate Certificates: While the limit is 50 per Registered Domain, if you have many subdomains and each is getting its own certificate (instead of consolidating them into one cert or using a wildcard), you can still hit the limit if your automation is misbehaving.

Step-by-Step Resolution

Follow these steps to diagnose and resolve the "too many certificates" error on your CentOS Stream / Rocky Linux system.

#### 1. Understand Let's Encrypt Rate Limits

Before proceeding, familiarize yourself with the current Let's Encrypt rate limits, especially "Certificates per Registered Domain". As of this writing, it's 50 certificates per week for a given Registered Domain. This means if you've issued 50 certificates for example.com and its subdomains within the last 7 days, you'll need to wait for the oldest ones to expire from the rolling 7-day window before new ones can be issued.

#### 2. Identify Existing Certificates

The first step is to see what certificates Certbot currently manages on your system.

sudo certbot certificates

This command will list all certificates, their names, domains, expiry dates, and paths.

Example Output:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: example.com
    Domains: example.com www.example.com
    Expiry Date: 2026-08-01 12:34:56 UTC (VALID: 30 days)
    Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
  Certificate Name: example.com-0001
    Domains: example.com www.example.com
    Expiry Date: 2026-07-28 08:00:00 UTC (VALID: 26 days)
    Certificate Path: /etc/letsencrypt/live/example.com-0001/fullchain.pem
  Certificate Name: staging.example.com
    Domains: staging.example.com
    Expiry Date: 2026-08-05 09:00:00 UTC (VALID: 34 days)
    Certificate Path: /etc/letsencrypt/live/staging.example.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Look for duplicate entries for the same domain set (e.g., example.com and example.com-0001 in the example, both covering example.com and www.example.com). These duplicates are often the cause of hitting rate limits.

#### 3. Clean Up Expired or Duplicate Certificates

Once you've identified duplicate or unwanted certificates, you should remove them.

Be extremely cautious when deleting certificates. Only delete certificates you are certain are duplicates, expired, or no longer in use. Deleting an active certificate that your web server is configured to use will cause your website to become inaccessible or display SSL errors.

To delete a certificate, use the certbot delete command with the --cert-name option:

sudo certbot delete --cert-name example.com-0001

Replace example.com-0001 with the actual Certificate Name you wish to remove. Certbot will prompt you to confirm the deletion. After deletion, run sudo certbot certificates again to verify cleanup.

#### 4. Check Certbot Configuration and Renewal Strategy

Ensure Certbot is configured to renew existing certificates rather than issue new ones.

4.1. Review Renewal Configuration Files

Examine the renewal configuration files located in /etc/letsencrypt/renewal/. Each .conf file corresponds to a certificate managed by Certbot.

sudo cat /etc/letsencrypt/renewal/example.com.conf

Look for authenticator and installer directives and ensure they are appropriate for your setup (e.g., nginx). More importantly, ensure there's nothing indicating a constant forced renewal.

4.2. Verify Automatic Renewal Mechanism

Let's Encrypt certificates are valid for 90 days, and it's best practice to renew them within 30 days of expiry. Certbot on CentOS/Rocky Linux typically sets up a systemd timer for automatic renewals.

Check the systemd timer status:

sudo systemctl list-timers | grep certbot

You should see output similar to this:

NEXT                         LEFT          LAST                         PASSED      UNIT                         ACTIVATES
Mon 2026-08-25 04:00:00 UTC  6h left       Sun 2026-08-24 04:00:00 UTC  18h ago     certbot-renew.timer          certbot-renew.service

If the timer is active, certbot-renew.service will execute certbot renew. This command is designed to only renew certificates that are due for renewal, not issue new ones unless explicitly told to.

Common Pitfall: If you're manually running commands, always use sudo certbot renew. Avoid certbot certonly or certbot run for routine renewals unless you have a specific, infrequent need to re-issue for different domain sets.

Never manually run sudo certbot renew --force-renewal unless you are absolutely certain the rate limit has reset and you need to force a renewal of an existing certificate, typically after resolving an underlying issue that prevented normal renewal. Repeatedly forcing renewals will hit rate limits even faster.

#### 5. Utilize Let's Encrypt Staging Environment

If you need to test Certbot commands or troubleshoot authentication issues without hitting production rate limits, use the staging environment.

To test a renewal dry-run:

sudo certbot renew --dry-run

To test a new certificate issuance (without installing it) using staging:

sudo certbot certonly --nginx -d example.com -d www.example.com --dry-run --staging

This will simulate the process but use the staging servers, which have much higher rate limits and do not count towards your production limits.

#### 6. Request a New Certificate (Carefully) or Wait

After cleaning up duplicates and correcting your renewal strategy, you have two options:

  1. Wait for the Rate Limit to Reset: This is often the safest and easiest solution if you've recently hit the limit. The "Certificates per Registered Domain" limit resets on a rolling 7-day basis. If you hit the limit today, you might need to wait up to a week for new certificate issuance attempts to succeed.

  2. Request a New Certificate (If Rate Limit Has Reset or Cleared): If you're confident the rate limit has reset or you had very few certificates and have since deleted duplicates, you can try issuing a new certificate.

    For a new certificate using the Nginx authenticator:

    sudo certbot certonly --nginx -d yourdomain.com -d www.yourdomain.com
    

    Certbot will attempt to obtain a new certificate and typically update your Nginx configuration. If it asks you to choose an existing certificate or obtain a new one, choose to obtain a new one only if you've confirmed the old ones are truly deleted or expired and your web server configuration is correct.

    If you're confident you need to renew an existing certificate that somehow failed and the rate limit should be clear, use:

    sudo certbot renew
    

    This is the standard command for renewal and is safe to run periodically.

#### 7. Verify Web Server Configuration

Ensure your Nginx server is configured to use the correct and latest certificates. Certbot usually handles this automatically when using the --nginx plugin, but it's good to double-check.

Locate your Nginx server block configuration for the domain, typically in /etc/nginx/nginx.conf or /etc/nginx/conf.d/yourdomain.conf.

Look for lines similar to these:

server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # ... other Nginx configurations
}

Ensure the ssl_certificate and ssl_certificate_key paths point to the correct live directory for your certificate name (e.g., yourdomain.com and not yourdomain.com-0001).

After any changes to Nginx configuration or successful certificate issuance/renewal, test and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Always run sudo nginx -t to test your Nginx configuration syntax before reloading or restarting. This prevents downtime due to configuration errors.

#### 8. Implement Proactive Monitoring

To prevent future unexpected certificate expirations or rate limit issues:

  • Monitor certbot renew --dry-run: Regularly check the output of sudo certbot renew --dry-run to ensure renewals would succeed.
  • External SSL Monitoring: Use external services like UptimeRobot, Checkly, or SSL monitoring tools (e.g., check_ssl_cert for Nagios, Prometheus exporters) to alert you when certificates are nearing expiration.
  • Review Logs: Periodically review /var/log/letsencrypt/letsencrypt.log for any warnings or errors.

By following these steps, you should be able to resolve the "too many certificates for domain" error and establish a robust, reliable Let's Encrypt renewal process on your CentOS Stream / Rocky Linux server.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

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.