-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
acme.sh implements ACME Renewal Information (RFC 9773) automatically. No flag, no opt-in, no configuration needed.
If your CA exposes a renewalInfo endpoint in its ACME directory (Let's Encrypt, ZeroSSL, Sectigo, SSL.com, …), acme.sh will use it. If the CA does not, acme.sh falls back to the classic 30-day fixed-interval rule — behavior is identical to before.
| What | When | Why |
|---|---|---|
🔍 Polls suggestedWindow
|
Every cron run, before deciding to skip | Lets the CA shift renewal forward in case of an incident (key compromise, mass revocation) |
| 🎯 Picks a random renewal time inside the window | Right after a successful issuance/renewal | Disperses renewals across the network so all clients don't hit the CA at the same instant |
🔗 Sends replaces=<certID> in newOrder |
On --renew
|
Lets the CA correlate the new order with the certificate it supersedes (RFC 9773 §5) |
↩️ Retries without replaces
|
If the CA returns alreadyReplaced or an ARI validation error |
Robust against edge cases (switching CAs, retired issuers, parallel renewal) |
acme.sh renews when any one of these is true:
-
--forceis given - The CA's ARI
suggestedWindow.starthas passed (so the CA is asking you to renew now) - The cached
Le_NextRenewTimehas passed (the classic 30-day fallback, also used when no ARI)
This means a CA can effectively command an early renewal across the entire acme.sh user base by shrinking the suggested window — useful for emergency incident response.
Short-lived certificates (Apple's 47-day proposal, Let's Encrypt's shortlived profile, etc.) are coming. With shorter lifetimes, fixed-interval renewal becomes brittle:
- A 7-day cert with a 30-day fixed renewal interval would always be expired
- All clients renewing at the same offset would hammer the CA
- Emergency revocations need a way to push the renewal time forward
ARI solves all three. The CA gets full control of when to renew; clients just follow its hints.
The chosen next-renewal time is saved in the domain conf as Le_NextRenewTimeStr:
acme.sh --info -d example.com
# Look for: Le_NextRenewTimeStr=...To see the live ARI window the CA is currently advertising, run with --debug 2:
acme.sh --renew -d example.com --debug 2 2>&1 | grep -i 'ARI suggestedWindow'Example output:
[INFO] ARI suggestedWindow: 2026-05-06T19:48:34Z to 2026-05-08T14:59:23Z
[INFO] Next renewal time picked from ARI window: 2026-05-07T16:57:49Z
-
certID for ARI requests is computed per RFC 9773 §4.1 as
base64url(AKI) + "." + base64url(Serial)of the existing certificate. -
Window pick is
start + (current_epoch % window_size). This is intentionally pseudo-random across clients (different cert issuance moments → different offsets) without needing crypto-grade randomness, and it is the same simple "use current time as entropy" pattern acme.sh already uses for cron randomization. -
Failure handling: any failure mode (ARI 404, network error, malformed response, CA does not support ARI) cleanly falls back to the original fixed-interval
Le_NextRenewTimelogic. ARI is a strict enhancement.
- Compatible with all validation modes: webroot, standalone, alpn, DNS API, DNS manual, DNS persist. ARI only changes when renewals happen, not how they validate.
-
Compatible with
--valid-to/--valid-from(Validity): when an explicit notAfter is set, acme.sh respects the user-provided deadline and does not let ARI override it. -
Compatible with
--cert-profile(Profile selection): independent.
- ✅ Let's Encrypt
- ✅ ZeroSSL (when ACME server returns
renewalInfo) - Check your CA's directory — if it has a
"renewalInfo"field, ARI is on.
curl -s https://acme-v02.api.letsencrypt.org/directory | grep renewalInfoFull normative reference: RFC 9773 — Automated Certificate Management Environment (ACME) Renewal Information (ARI) Extension
Key sections:
- §4.1 — certID computation
- §4.2 —
suggestedWindowshape - §4.3 — polling and
Retry-After - §5 — newOrder
replacesfield - §7.4 —
alreadyReplacederror code
Buy me a beer, Donate to acme.sh if it saves your time. Your donation makes acme.sh better: https://donate.acme.sh/
如果 acme.sh 帮你节省了时间,请考虑赏我一杯啤酒🍺, 捐助: https://donate.acme.sh/ 你的支持将会使得 acme.sh 越来越好. 感谢