6-Day Certificates Are Here: Auditing Renewal Automation That Assumed 90 Days
For a decade the number "90 days" was baked into how we ran TLS. Renew at day 60, alert at day 30, and if a certificate ever got within a week of expiry, something had gone badly wrong and a human went looking. That mental model was so reliable that most teams stopped thinking about it. The cron job ran, the dashboard stayed green, everyone moved on.
That model is now a liability. In January 2026 Let's Encrypt made short-lived certificates generally available: a shortlived profile that issues certificates valid for 160 hours, just over six days, and IP-address certificates that are mandatorily short-lived. This is not a Let's Encrypt quirk. The whole CA industry is moving toward much shorter lifetimes, and your renewal automation was written for a world that is ending.
Here is the thesis, and it is uncomfortable: most teams will "adapt" to six-day certificates by turning off the expiry alert that keeps firing, because it is noisy. That is exactly backwards. A noisy expiry alert on a six-day cert is not noise, it is your renewal cadence telling you it is too slow. If you silence it instead of tightening the cadence, you have removed the only warning you will get before a real outage.
Shrinking certificate lifetimes break three assumptions at once. Fix all three:
- Cadence: renew far more often. On a 6-day cert, renew daily (or twice daily) with jitter, not weekly.
- Alerting: stop hardcoding "alert 30 days before expiry." Alert on renewal failure directly, and set the expiry threshold as a fraction of lifetime, not a constant.
- Revocation: stop leaning on OCSP. A cert that lives six days expires before revocation would matter; the short lifetime is the revocation mechanism.
Why the old assumptions break
Every piece of certificate automation encodes an assumption about lifetime somewhere. When lifetime drops from 90 days to 6, those assumptions do not fail loudly. They quietly become wrong.
Assumption 1: "renew at day 60" was a ratio, disguised as a constant
Renewing a 90-day cert at day 60 leaves a 30-day safety margin, a third of the lifetime, for retries when validation fails. Certbot's default is to renew when a cert is within 30 days of expiry, which on a 90-day cert means it starts trying around day 60 and has a month of daily attempts to succeed before anything is at risk.
On a 6-day cert, "within 30 days of expiry" means always, which is fine, but the safety margin collapses. If your renewal only runs weekly, the cert can expire between runs. The correct margin is still a ratio of lifetime, not a fixed number of days. Aim to renew when roughly one third of the lifetime remains and to attempt renewal several times within the remaining window, which for a six-day cert means running at least daily.
Assumption 2: "alert 30 days before expiry" now fires on a cert that is already dead
A monitoring rule that pages when a cert has fewer than 30 days left will page continuously for a certificate whose entire life is six days. Teams see a permanently red check, decide it is broken, and disable it. Now nothing watches the certificate at all, and the first sign of a broken renewal loop is a browser error from a customer.
Assumption 3: OCSP was your revocation story, and it is now irrelevant
Revocation via OCSP or CRLs exists to un-trust a certificate before it naturally expires, for example after a key compromise. For a 90-day cert that window can be almost three months. For a six-day cert it is at most six days, and in practice much less. Let's Encrypt has already ended OCSP support. If your architecture depends on OCSP stapling or OCSP checks as a security control, short-lived certs make that control close to meaningless, and you should stop treating it as one.
The audit: five checks against your current setup
This is a decision-and-audit article, not a single command, because the fix depends on what you already run. Work through these in order.
Check 1: How often does renewal actually run?
Find the timer or cron entry that drives renewal and read its schedule, not your memory of it. On a systemd-based host:
systemctl list-timers 'certbot*' 'snap.certbot*'
Certbot's own packaged timer already runs twice a day, which is correct for short-lived certs. The danger is home-grown automation. If you find a crontab line that renews weekly or monthly, that is the first thing to change. For the tradeoffs between cron, systemd timers and framework schedulers, I went deep in Cron vs systemd Timers vs the Frappe Scheduler.
Check 2: Add jitter so a fleet does not renew in lockstep
If a hundred servers all renew at 03:00, you have built a thundering herd against the CA's rate limits, and short-lived certs mean that herd hits far more often. Spread it. A systemd timer does this with:
# /etc/systemd/system/certbot-renew.timer
[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=3600
Persistent=true
RandomizedDelaySec=3600 scatters each run across a one-hour window, and Persistent=true means a machine that was asleep at the scheduled time runs the job on wake instead of silently skipping it. In cron you get the same effect with a sleep $((RANDOM \% 3600)) before the renew command.
Check 3: Alert on renewal failure, not just on approaching expiry
The most important change. Your primary signal should be "the renewal command exited non-zero" or "no successful renewal in the last N hours," because that catches the problem while there is still time to fix it. Expiry-based alerting is a backstop, not the front line. Wire the renew command so failure is visible; on a mail-configured host, systemd's OnFailure= or a wrapper that curls a heartbeat service both work. I walk through the silent-failure trap in detail in Certbot renewal fails silently, and it matters far more now than it did at 90 days.
Check 4: Rewrite expiry thresholds as a fraction of lifetime
If you must keep an expiry check, make the threshold proportional. Instead of "alert if fewer than 30 days remain," alert if fewer than, say, 30 percent of the certificate's total lifetime remains. For a six-day cert that is under two days left, which is a genuine emergency worth paging for; for a 90-day cert it is 27 days, comfortably early. One rule, correct at both lifetimes.
| Lifetime | Renew when | Run interval | Page when remaining |
|---|---|---|---|
| 90 days | ~30 days left | Twice daily is plenty | < ~27 days (30%) |
| 6 days (160h) | ~2 days left | At least daily, ideally 2x | < ~1.8 days (30%) |
Check 5: Test renewal for real with staging
Do not discover a broken renewal path in production. Force a dry run and, before switching a client to short-lived certs, rehearse against Let's Encrypt's staging environment so a broken loop burns test quota instead of your real rate limit:
certbot renew --dry-run
Expected output ends with a line reporting success for each configured certificate. If any report a failure, that certificate would have expired unrenewed, and on a six-day clock you would have found out within days. My argument for making staging the default is in Your Cert Automation Should Default to Let's Encrypt Staging.
Verification: prove the new cadence holds
After changing the schedule, confirm the timer will actually fire soon and often:
systemctl list-timers 'certbot-renew.timer'
The NEXT column should show a run within the next twelve hours, and after a day of operation the LAST column should show a recent successful pass. Then check the live certificate's remaining life so you can see the renewal is keeping it fresh rather than letting it drift toward zero:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -enddate
On a healthy six-day setup this date should never be more than a couple of days out, and it should visibly move forward each time you check across a few days. A date that stays static while the clock advances means renewal is not reaching the served certificate, which sends you back to Check 1.
What people get wrong
Silencing the expiry alert because it "won't stop firing." Already said, worth repeating because it is the single most damaging reaction. A short-lived cert that trips a 30-day threshold is not misconfigured monitoring, it is a monitoring rule written for the wrong era. Fix the rule, do not mute it.
Keeping OCSP stapling as a security requirement. Some hardening checklists still mandate OCSP stapling. Against a six-day certificate the revocation window it protects is shorter than the cert's own life, so it buys almost nothing. Do not block a deployment on it, and do not let a scanner's OCSP finding drive your priorities here.
Treating IP-address certs as normal certs. Let's Encrypt's IP-address certificates are short-lived by design and cannot be issued long. If you plan to serve TLS on a bare IP, build the fast renewal loop from day one rather than retrofitting it after the first expiry.
When it is still broken
If certificates keep expiring despite a tightened schedule, the renewal is running but not succeeding, and the cause is usually the validation challenge, not the timer. Walk the challenge path: confirm the HTTP-01 or DNS-01 flow still reaches the CA, check for a proxy or CDN intercepting the challenge, and read the renewal log rather than assuming. If you hit issuance limits while testing frequent renewals, that is a separate wall covered in "Too Many Certificates Already Issued".
The authoritative source for the profile name and lifetime is Let's Encrypt's own general availability announcement. Read it, then go look at the one cron line that has been quietly protecting your production TLS, and ask whether it still assumes 90 days.
Frequently asked questions
- How often should I renew a 6-day Let's Encrypt certificate?
- At least once a day, and twice a day is safer. A six-day certificate leaves no room for a weekly schedule, because a single missed run can let it expire before the next attempt. Certbot's packaged timer already runs twice daily, which is appropriate; the risk is home-grown weekly or monthly cron jobs.
- Should I turn off my certificate expiry alert now that it fires constantly?
- No. An expiry alert that keeps firing on a short-lived certificate is telling you the renewal cadence is too slow, not that the alert is broken. Change the threshold to a fraction of the certificate's lifetime instead of a fixed 30 days, and add a separate alert on renewal failure as your primary signal.
- Do I still need OCSP with short-lived certificates?
- Effectively no. Revocation via OCSP exists to un-trust a certificate before it expires, but a six-day certificate expires before any meaningful revocation window matters, so the short lifetime is the revocation mechanism. Let's Encrypt has already ended OCSP support, so do not architect around it.
- What is the shortlived profile in Let's Encrypt?
- It is the ACME certificate profile you select to be issued a short-lived certificate, valid for 160 hours which is just over six days, rather than the standard roughly 90-day certificate. IP-address certificates from Let's Encrypt are mandatorily short-lived and use the same short lifetime.