When running a web server on CyberPanel (which uses acme.sh under the hood), SSL certificates are usually issued automatically. But one morning, I found my SSL renewals timing out — the logs showed connections to acme.zerossl.com. Eventually, they started throwing 429 rate-limit errors from Let’s Encrypt after I switched CAs.

Here’s everything I did to fix it — step by step.

The Problem

CyberPanel by default uses acme.sh to manage SSL certificates. For a long time, it pointed to ZeroSSL as the default certificate authority (CA).

After a few successful renewals, my logs started showing this:

[Tue Oct 7 05:58:59 AM UTC 2025] code='429'
[Tue Oct 7 05:58:59 AM UTC 2025] "too many certificates (5) already issued for this exact set of identifiers..."

I was hitting the Let’s Encrypt rate limit (5 certs per week per domain set). Before that, ZeroSSL itself was timing out.

I realized that:

acme.sh was still defaulting to ZeroSSL.

I needed to switch my CA back to Let’s Encrypt permanently.

I didn’t actually need a new certificate — the last one was still valid.

Step 1: Check Which CA You’re Using

Run this command:

~/.acme.sh/acme.sh --show-ca

If it outputs something like:

CA: https://acme.zerossl.com/v2/DV90

then you’re still using ZeroSSL.

Step 2: Set Let’s Encrypt as Default CA

To switch temporarily for just one certificate:

/root/.acme.sh/acme.sh --issue -d example.com --standalone --server letsencrypt

If the cert already exists under ZeroSSL and you just want to re-issue it via Let’s Encrypt:

/root/.acme.sh/acme.sh --renew -d example.com --force --server letsencrypt

To switch permanently:

/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt

If you haven’t registered your Let’s Encrypt account yet:

/root/.acme.sh/acme.sh --register-account -m you@example.com --server letsencrypt

This tells acme.sh to use Let’s Encrypt for all new issues/renewals.

Step 3: Check Existing Certificates

To see details for any domain:

~/.acme.sh/acme.sh --info -d yourdomain.com

Example output (simplified):

Le_API=https://acme-v02.api.letsencrypt.org/directory
Le_CertCreateTimeStr=2025-10-06T09:36:11Z
Le_NextRenewTimeStr=2025-12-04T09:36:11Z
Le_RealCertPath=/etc/letsencrypt/live/yourdomain.com/cert.pem

If it shows Let’s Encrypt under Le_API, you’re already good.

Step 4: Install the Existing Certificate

If the certificate already exists and you just need to deploy it (without re-issuing and hitting rate limits):

~/.acme.sh/acme.sh --install-cert -d yourdomain.com \
  --cert-file      /etc/letsencrypt/live/yourdomain.com/cert.pem \
  --key-file       /etc/letsencrypt/live/yourdomain.com/privkey.pem \
  --fullchain-file /etc/letsencrypt/live/yourdomain.com/fullchain.pem \
  --reloadcmd     "systemctl reload lsws || /usr/local/lsws/bin/lswsctrl reload"

After that, you should see:

Reload successful

Step 5: Verify the Installed Certificate

Check if your certificate was issued by Let’s Encrypt:

openssl x509 -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem -noout -issuer -enddate -subject

Expected output:

issuer= C = US, O = Let's Encrypt, CN = E8
notAfter=Jan  4 08:37:39 2026 GMT
subject=CN = yourdomain.com

Step 6: Fix the Renewal and Reload Automation

Ensure acme.sh knows how to reload your web server when certificates renew:

grep Le_ReloadCmd ~/.acme.sh/yourdomain.com_ecc/yourdomain.com.conf

If it’s blank, set it again:

~/.acme.sh/acme.sh --install-cert -d yourdomain.com \
  --cert-file      /etc/letsencrypt/live/yourdomain.com/cert.pem \
  --key-file       /etc/letsencrypt/live/yourdomain.com/privkey.pem \
  --fullchain-file /etc/letsencrypt/live/yourdomain.com/fullchain.pem \
  --reloadcmd "systemctl reload lsws || /usr/local/lsws/bin/lswsctrl reload"

Confirm a cron job exists for automatic renewals:

crontab -l | grep acme.sh

If not, add one:

~/.acme.sh/acme.sh --install-cronjob

Step 7: (Optional) Fix the CyberPanel Hostname SSL

The CyberPanel admin panel’s SSL is separate from your websites.
Go to:

CyberPanel → SSL → Hostname SSL → Issue SSL

Now that the default CA is Let’s Encrypt, it will use it automatically.

Step 8: Testing and Confirmation

Test your site:

curl -I https://yourdomain.com

And confirm the certificate chain from anywhere:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null | openssl x509 -noout -issuer -enddate

If you see “Let’s Encrypt” and a valid expiry date — you’re done.

Final Notes

Don’t use --force unless you need to re-issue. Each forced run counts toward your 5-per-week limit.

acme.sh keeps logs under /root/.acme.sh/acme.sh.log — check here if something goes wrong.

CyberPanel users can safely use CLI commands for troubleshooting — the panel will pick up changes automatically.

TL;DR — Quick Recovery Cheatsheet

StepCommandPurpose
Check CA~/.acme.sh/acme.sh –show-caSee if it’s ZeroSSL or LE
Switch CA–set-default-ca –server letsencryptMake LE default
Check cert–info -d domain.comSee issuance details
Install cert–install-cert …Deploy without reissuing
Verify certopenssl x509 -in … -issuer -enddateCheck LE issuer
Cron renew–install-cronjobEnsure auto renewals
Reload websystemctl reload lswsApply the new cert

Lessons Learned

  • CyberPanel doesn’t automatically switch to Let’s Encrypt after acme.sh updates — you must set it yourself.
  • Forcing re-issues too many times quickly hits Let’s Encrypt’s rate limits.
  • The existing valid certificate can simply be installed and reloaded — no need to re-request it.

Leave a comment