ACME Renewal Settings for 64-Day Certificates
Where Certbot, cert-manager, Caddy, lego, acme.sh, Traefik and win-acme keep their renewal threshold, and what each does with a 64-day certificate.
Ben Ennis
Published October 27, 2026
Let’s Encrypt’s October 7 announcement is short on instructions because, for most people, there is nothing to do. If your client supports ARI, the CA tells it when to renew. If it doesn’t, the post asks you to renew at about two-thirds of the lifetime and to search cron jobs and runbooks for hard-coded numbers like 83, 80 or 60.
Searching for “60” in a config tree finds a lot of things that aren’t renewal settings. This is the narrower list: for each common client, where the threshold lives, what the default does to a 64-day certificate, and how a stored value from an older version can survive an upgrade.
Two kinds of threshold
Every client answers one question: when is a certificate due? There are two ways to express it, and only one survives a lifetime change.
- Relative to expiry or lifetime. “Renew with a third of the lifetime left” or “renew 30 days before notAfter.” These read the certificate’s real dates, so a 64-day certificate gets a sensible schedule.
- Relative to issuance. “Renew 60 days after the certificate was created.” This made sense when every certificate lasted 90 days. On a 64-day certificate it leaves four days of margin, and on a 45-day certificate it schedules renewal after expiry.
ARI, standardized in RFC 9773, sits above both. The client asks the CA for a suggested renewal window for each certificate. For Let’s Encrypt certificates that window falls at about two-thirds of the lifetime. A client that honors ARI will also renew early if the CA needs to replace certificates after an incident, which no local setting can do.
What each client does with a 64-day certificate
The day numbers assume a 64-day certificate, a client run at least daily, and no ARI unless the row says so.
| Client | Default rule | Renews on day | Setting that breaks it |
|---|---|---|---|
| Certbot 4.0+ | 1/3 of lifetime left, ARI from 4.1 | about 43 | renew_before_expiry set long |
| Certbot before 4.0 | 30 days before expiry | 34 | renew_before_expiry above 60 days |
| cert-manager | 2/3 through the duration | about 43 | absolute renewBefore near 64 days |
| Caddy | 1/3 of lifetime left, plus ARI | about 43 | renewal_window_ratio near 1 |
| lego v5 | 1/3 of lifetime left, plus ARI | about 43 | --renew-days above 60 |
| lego v4 | 30 days before expiry | 34 | --days above 60 |
| acme.sh 3.1.3+ | ARI, else 30 days after issue | about 43 with ARI | a stored --days 60 with ARI off |
| acme.sh 3.1.2 and older | 60 days after issue | 59 | the default itself |
| Traefik | 30 days before expiry | 34 | certificatesDuration set to 1536 |
| win-acme | 55 days after issue, ARI can pull earlier | about 43 with ARI, 55 without | ARI disabled |
Certbot
Certbot 4.0.0 changed the default from a fixed 30 days before expiry to renewing with a third of the lifetime left. Certbot 4.1.0 added ARI and notes that, for Let’s Encrypt, this typically means renewal at about two-thirds of the lifetime, even if a renewal config asks for a later date. The current user guide describes the same rule.
The setting to look for is renew_before_expiry in each lineage file under /etc/letsencrypt/renewal/. It still overrides the default when ARI is not available. Distribution packages lag upstream, so check the version too:
certbot --version
grep -H renew_before_expiry /etc/letsencrypt/renewal/*.conf
A value like 30 days is harmless on a 64-day certificate. A value of 60 days or more is the one Let’s Encrypt is warning about.
cert-manager
cert-manager renews 2/3 of the way through the issued certificate’s duration by default. spec.renewBefore sets an absolute time before expiry, and spec.renewBeforePercentage sets it as a share of the real duration. The docs recommend the percentage form, specifically to avoid renewal loops when the CA issues a shorter certificate than you asked for.
That is exactly what happens on February 10. A Certificate with renewBefore: 1440h (60 days) asks for renewal four days after each issuance. List the values and the computed renewal time across the cluster:
kubectl get certificates -A -o custom-columns=\
NS:.metadata.namespace,NAME:.metadata.name,\
BEFORE:.spec.renewBefore,PCT:.spec.renewBeforePercentage,\
RENEWAL:.status.renewalTime
Empty BEFORE and PCT columns mean the 2/3 default applies, and that’s the setting you want.
Caddy
Caddy’s global options set renewal_window_ratio to 0.3333 by default, so it renews with a third of the lifetime left. The docs also note that a CA’s ARI window takes precedence. Unless someone set the ratio deliberately, Caddy needs nothing. Search the Caddyfile and any JSON config for renewal_window_ratio.
lego
lego v5 computes the renewal time from the certificate’s lifetime by default: a third of the lifetime left, or half for short-lived certificates. It checks ARI unless ari.disable is set, according to the configuration file reference. The v4 to v5 migration notes rename --days to --renew-days and make the old --dynamic behavior the default.
lego v4’s renew command renews when fewer than 30 days remain, per its renewal docs. That gives day 34 on a 64-day certificate, which is fine. Look for cron entries or systemd units that pass --days or --renew-days with a large value.
acme.sh
acme.sh is the client most likely to need attention, because its --days setting counts from issuance, not expiry. An acme.sh issue closed in July spells out the formula: next renewal = creation time + --days - 1 day, with no check against notAfter. A negative --days counts back from expiry instead.
The default changed between releases. In the source of tag 3.1.2 (November 2025), DEFAULT_RENEW is 60, so a 64-day certificate is scheduled for day 59. Tag 3.1.3 (April 2026) lowered it to 30 and added the first ARI code. The acme.sh ARI page says ARI now needs no flag. A --days or --valid-to you passed yourself pins the schedule, but ARI can still move a pinned renewal earlier. NO_ARI=1 turns ARI off.
The catch is that acme.sh writes Le_RenewalDays and the next renewal time into each domain’s config. Upgrading the script doesn’t rewrite a schedule an old version stored:
~/.acme.sh/acme.sh --version
grep -H -E '^Le_RenewalDays=|^Le_NextRenewTimeStr=' ~/.acme.sh/*/*.conf
Any Le_RenewalDays=60 on a host that also sets NO_ARI=1 will renew a 64-day certificate five days before it expires.
Traefik
Traefik doesn’t implement ARI yet. The feature request is open. Instead, its ACME documentation has a certificatesDuration option that only controls renewal timing. At the default of 2160 hours, Traefik renews 30 days before expiry and checks once a day, so a 64-day certificate renews on day 34.
The trap is the obvious fix. Setting certificatesDuration: 1536 to “match” a 64-day certificate moves it into the table’s 30-to-90-day bucket, where the renewal period is 10 days. Renewal then waits until day 54. Leave the default unless you also use a much shorter profile.
win-acme
win-acme’s settings reference sets RenewalDays to 55, counted from issuance. That leaves nine days on a 64-day certificate. ARI arrived in win-acme 2.2.3 and only moves renewals earlier, so with the default RenewalDisableServerSchedule: false the CA’s window wins and renewal happens around day 43. If that setting is true, lower RenewalDays to about 42.
Test against staging before February
Let’s Encrypt began issuing 64-day certificates in staging on October 14. Issue one staging certificate per client type and read back the renewal time the client computed, not just the expiry date. acme.sh shows it with --info, cert-manager in status.renewalTime, and win-acme in its renewal list. For Certbot, run certbot renew --dry-run against staging to confirm the hooks, then check the lineage config for overrides.
The announcement also cuts authorization reuse from 30 days to 10. That matters only for clients built to skip validation on renewal. If your renewals depend on a DNS-01 record that a person updates by hand, assume each renewal needs a fresh challenge.
Check from the outside
Config files tell you what a client intends to do. Certificate Transparency shows what it actually did. The certificate lifetime checker reads a host’s logged certificates and reports the median days left at each renewal. A host that renews with about 30 days left on 90-day certificates fits 64-day certificates. One that renews with about 60 days left is likely running one of the fixed rules above. The explainer covers how the checker reads renewal series.
When we charted 28 developer domains in the week 43 recap, 17 renewed with about 30 days left and five with about 60. Those five are the ones to look at first. After any change, confirm that the certificate the host serves is the new one with the TLS inspector. Several of the failures in our ACME renewal post-mortem passed every renewal check and still served the wrong thing.
Recommended reading
- Let’s Encrypt integration guide: checking ARI twice a day, and the one-third backstop.
- CA/Browser Forum Ballot SC-081: the 100-day limit for every public CA from March 15, 2027.
- Why ACME renewal quietly broke: chain, EKU and OCSP changes that renewal logs don’t show.
Frequently asked questions
When do Let's Encrypt certificates become 64 days?+
Do I need to change anything if my client supports ARI?+
Is renewing 30 days before expiry still safe?+
Why is acme.sh singled out?+
Should I set Traefik's certificatesDuration to 1536 hours?+
How can I check a host I don't manage?+
Tags: #acme, #lets-encrypt, #tls, #certbot, #cert-manager, #renewal