TRENDING
A metal tap in silhouette beside a window with drops of water falling from its spout
October 12, 2026
How to Find and Fix a Memory Leak in a Python Service With tracemalloc
A split-flap arrivals board at Łódź Kaliska railway station in Poland listing trains by time and platform, a picture of a fixed timetable
October 12, 2026
Ai2’s GPU Scheduler Turns Priority Into a Budget, but Leaves the Preemption Bill Unreported
Close-up of an industrial machine operator control panel with a red emergency stop button, push buttons, a handwheel and a display screen
October 12, 2026
Booz Allen Says Frontier AI Met All Eight Attack Goals in Its OT Lab, With a Human Approving Every Exploit
A brushed-metal hotel key fob stamped with the number 21 on a ring with a brass key, lying on grey-green carpet
October 12, 2026
How to Evolve a Protobuf Schema Without Breaking Old Clients and Block Unsafe Edits in CI With Python
Red emergency brake handle on a brushed steel plate inside a train, with a label reading Hätäjarru, Nödbroms and Emergency brake
October 12, 2026
Nadella’s Insider-Risk Essay Turns AI Containment Into an Access-Control Test From the 1970s
12 Oct 2026
SXZ.io SXZ.io
  • Home
Search the Site
Popular Searches:
Technology Amazon AI
Recent Posts
Two climbers in helmets and backpacks walk up a snow slope, joined by a taut rope between them
How to Replace asyncio.gather With TaskGroup in Python and Handle Failures With except*
October 12, 2026
A gray parking meter with a red EXPIRED flag in its window and a dark parked car blurred behind it
Let’s Encrypt’s 64-Day Default Turns Hard-Coded Renewal Numbers Into a Deadline
October 12, 2026
Aerial view of a worn dirt desire line cutting straight across a hillside beside a curving paved trail
Attackers Probed a CVSS 10 SonicWall SMA1000 Flaw Two Days After Its Patch, the Third Such Fix in 12 Weeks
October 12, 2026
SXZ.io SXZ.io
  • Home

Categories

Articles 238 Posts
News 241 Posts
Learning Hub 211 Posts
Home/Articles/Let’s Encrypt’s 64-Day Default Turns Hard-Coded Renewal Numbers Into a Deadline
Articles

Let’s Encrypt’s 64-Day Default Turns Hard-Coded Renewal Numbers Into a Deadline

Let’s Encrypt will issue 64-day certificates by default from February 10, 2027; no Baseline Requirements date forces that step, but it is the first one that breaks renewal scripts and alerts keyed to...

October 12, 2026 12 Min Read
7

Let’s Encrypt will issue 64-day certificates by default starting February 10, 2027, and its announcement tells subscribers how to find the scripts that will break: “Grep for common hardcoded numbers like 83, 80 or 60 in cron jobs, wrapper scripts and runbooks if you’re not sure.” The post is dated October 7, 2026, and SecurityWeek covered it on October 12.

Table Of Content

  • What changes, and on which dates
  • The Forum’s schedule is looser than Let’s Encrypt’s
  • Why 64 days breaks age-based renewal
  • The common clients already renew by fraction
  • What the CA’s own renewal hint says
  • What I could not test
  • Monitoring: the alert that survives 64 days with 1.3 days to spare
  • Authorization reuse, and the fix that has not shipped
  • A checklist before February
  • The bottom line
  • Sources and method

Those three numbers carry the whole story. A rule that renews on day 60 works at 90 days, leaves four days of margin at 64 and fails outright at 45, and rules that renew on day 80 or 83 fail at 64. An alert that warns below 20 days stays quiet through healthy 64-day renewals with 1.3 days to spare and fires on healthy 45-day ones. I checked the CA/Browser Forum schedule, asked Let’s Encrypt’s renewal-information endpoint about 18 live certificates and read the renewal defaults of three widely used certificate clients. Two findings go beyond the announcement. No Baseline Requirements date forces the 64-day step, and the DNS validation fix that Let’s Encrypt promised alongside shorter lifetimes still has no production date.

What changes, and on which dates

The dates below come from Let’s Encrypt’s December 2025 post, the October 7 post and the profiles page, which was last updated on October 4, 2026. They apply to the default classic profile.

Date Classic profile Source
Now 90-day certificates, 30-day authorization reuse Profiles page
October 14, 2026 Staging issues 64-day certificates October 7 post
February 10, 2027 64-day certificates, 10-day authorization reuse December 2025 and October 7 posts
May 11, 2027 Last 90-day certificate expected to expire October 7 post
February 16, 2028 45-day certificates, 7-hour authorization reuse December 2025 post

Subscribers who choose a profile can already run shorter lifetimes. The tlsserver profile issues 45-day certificates, and the shortlived profile issues certificates valid for 160 hours, which the profiles page calls “6ish days.” Let’s Encrypt says it will not revoke valid certificates in the switch and that the change does not affect ACME endpoints or issuance chains. On rate limits it says “Rate limits will not be impacted by this change” and points to an earlier post.

The Forum’s schedule is looser than Let’s Encrypt’s

Let’s Encrypt’s December post says the shorter lifetimes are being introduced “along with the rest of the industry, as required by the CA/Browser Forum Baseline Requirements,” so I read the Baseline Requirements text itself. It was version 2.3.1 on October 12, and it sets these ceilings by issuance date.

Issued on or after Maximum certificate validity Maximum domain validation reuse
March 15, 2026 200 days 200 days
March 15, 2027 100 days 100 days
March 15, 2029 47 days 10 days

Neither 64 nor 45 appears anywhere in that text. Let’s Encrypt’s 90-day certificates already fit under the 100-day ceiling that starts on March 15, 2027, so nothing in the Forum’s table requires the February 10 step, which lands 33 days before that date. The 45-day step on February 16, 2028 lands 393 days before the 47-day ceiling. The reuse cut runs on the same early timetable. Let’s Encrypt ties it to “a 2029 reduction in maximum validation reuse periods,” and its 10-day reuse period starts 764 days before the Forum’s 10-day maximum. SecurityWeek says the change is “in line with” the Baseline Requirements, which is right about the direction. The dates are Let’s Encrypt’s own, and its stated reason is security: “We are moving to shorter certificate lifetimes because this reduces the risk of key compromise and mis-issuance.”

My reading is that Let’s Encrypt is giving automated subscribers a staged runway instead of one cliff in March 2029, so its subscribers will meet short lifetimes earlier than the Forum’s table requires. The sample I probed shows who is not there yet. Of the 31 certificates I could read from 32 technical sites, all 18 from Let’s Encrypt and all seven from Google Trust Services ran 90 days. The three from other commercial CAs issued after March 15, 2026 ran 178 to 199 days, inside the current 200-day ceiling, and the three issued earlier ran 397 days. The Forum’s 100-day step in March 2027 changes nothing for the 25 certificates from Let’s Encrypt and Google and cuts the lifetimes of the other six.

Why 64 days breaks age-based renewal

Renewal rules come in two kinds. An age-based rule renews when a certificate is a set number of days old. A remaining-based rule renews when a set number of days are left. At 90 days the two look identical, because day 60 and 30 days left are the same moment. They part ways as soon as the lifetime changes, and the table shows how. My reading of the numbers in Let’s Encrypt’s grep advice is that 83, 80 and 60 are age-based versions of 7, 10 and 30 days left on a 90-day certificate. The post does not say so.

Renewal rule 90-day certificate 64-day certificate 45-day certificate 160-hour certificate
Renew on day 60 (30 days left of 90) Renews, 30.0 days left Renews, 4.0 days left Expires 15.0 days before the rule fires Expires 53.3 days before the rule fires
Renew on day 80 (10 days left of 90) Renews, 10.0 days left Expires 16.0 days before the rule fires Expires 35.0 days before the rule fires Expires 73.3 days before the rule fires
Renew on day 83 (7 days left of 90) Renews, 7.0 days left Expires 19.0 days before the rule fires Expires 38.0 days before the rule fires Expires 76.3 days before the rule fires
Renew with 30 days left (fixed) Renews on day 60.0 Renews on day 34.0 Renews on day 15.0 Due on every run
Renew with a third left (a half for 10 days or less) Day 60.0, 30.0 days left Day 42.7, 21.3 days left Day 30.0, 15.0 days left Day 3.3, 3.3 days left

The day-60 rule survives 64 days with four days to spare, which leaves little room for a failed run over a weekend. The day-80 and day-83 rules never fire before expiry, and all three age-based rules fail at 45 days. Remaining-based rules degrade more gently, because they renew earlier and more often instead of too late. Renewing at two thirds of the lifetime means 6.1 issuances per name per year at 90 days, 8.6 at 64 and 12.2 at 45, by my arithmetic, so the renewal path has to be boring enough to run that often.

The common clients already renew by fraction

Three widely used clients already express the threshold as a fraction of the lifetime. Certbot’s documentation says “As of Certbot 4.0.0, a certificate is considered ready for renewal when less than 1/3rd of its lifetime remains.” For lifetimes of 10 days or less the threshold is half, and “Prior to Certbot 4.0.0 the threshold was a fixed 30 days.” cert-manager documents the default for its renewBefore field in its API source: “If unset, this defaults to 1/3 of the issued certificate’s lifetime.” CertMagic, the library the Caddy web server uses, sets DefaultRenewalWindowRatio = 1.0 / 3.0 in maintain.go, with the comment “A default value of ~1/3 is pretty safe and recommended for most certificates.” Upgrading the client is usually enough. That leaves the hand-written parts, such as cron lines, wrapper scripts, deployment variables and runbooks that still carry a number from the 90-day era.

What the CA’s own renewal hint says

ACME Renewal Information (ARI), standardized as RFC 9773 in June 2025, lets a client ask the CA when to renew. The CA answers with a suggested window, and the RFC says “Clients MUST attempt renewal at a time of their choosing based on the suggested renewal window.” Let’s Encrypt’s integration guide adds an incentive: “certificate renewals that utilize ARI will now be exempt from all rate limits” as long as “renewals must occur within the ARI-suggested renewal window, and the request must clearly indicate which existing certificate is being replaced.” For clients that support it, the October 7 post says “you should be all set” because ARI lets Let’s Encrypt tell the client when to renew.

I wanted to see what the endpoint returns today. The script below reads the certificate a site serves and builds the ARI certificate identifier, which is the base64url of the Authority Key Identifier’s key identifier, a dot, and the base64url of the serial number’s DER integer body, with no padding. It then prints the suggested window. I ran it on Python 3.13 with cryptography 50.0.1 and requests 2.34.2. It works only for certificates that Let’s Encrypt issued. For any other CA the endpoint answers 404, and raise_for_status() turns that into an error.

# ari_check.py
# When does Let's Encrypt suggest renewing the certificate a site serves right now?
# pip install cryptography requests. Works for hosts whose certificate Let's Encrypt issued.
import base64
import socket
import ssl
import sys
from datetime import datetime

import requests
from cryptography import x509
from cryptography.x509.oid import ExtensionOID

ARI = "https://acme-v02.api.letsencrypt.org/acme/renewal-info/"  # the "renewalInfo" URL in the ACME directory


def b64(raw: bytes) -> str:
    return base64.urlsafe_b64encode(raw).rstrip(b"=").decode()


def served_cert(host: str) -> x509.Certificate:
    ctx = ssl.create_default_context()
    with socket.create_connection((host, 443), timeout=8) as sock:
        with ctx.wrap_socket(sock, server_hostname=host) as tls:
            return x509.load_der_x509_certificate(tls.getpeercert(binary_form=True))


def cert_id(cert: x509.Certificate) -> str:
    aki = cert.extensions.get_extension_for_oid(ExtensionOID.AUTHORITY_KEY_IDENTIFIER).value.key_identifier
    n = cert.serial_number
    serial = n.to_bytes((n.bit_length() + 8) // 8, "big")  # the DER INTEGER body, with a leading 0x00 when needed
    return b64(aki) + "." + b64(serial)


def when(ts: str) -> datetime:
    return datetime.fromisoformat(ts.replace("Z", "+00:00"))


host = sys.argv[1]
cert = served_cert(host)
nb, na = cert.not_valid_before_utc, cert.not_valid_after_utc
life = (na - nb).total_seconds()
r = requests.get(ARI + cert_id(cert), timeout=10)
r.raise_for_status()
w = r.json()["suggestedWindow"]
start, end = when(w["start"]), when(w["end"])
print(f"{host}: valid {nb:%Y-%m-%d} to {na:%Y-%m-%d} ({life / 86400:.2f} days)")
print(f"suggested window: {start:%Y-%m-%d %H:%M} to {end:%Y-%m-%d %H:%M} UTC ({(end - start).total_seconds() / 3600:.1f} hours)")
opens = (start - nb).total_seconds()
print(f"window opens {opens / 86400:.2f} days in, {opens / life:.1%} of the lifetime, {(na - start).total_seconds() / 86400:.2f} days before expiry")
print(f"Retry-After: {r.headers.get('Retry-After')} seconds")
letsencrypt.org: valid 2026-09-04 to 2026-12-03 (90.00 days)
suggested window: 2026-11-02 17:18 to 2026-11-04 12:29 UTC (43.2 hours)
window opens 59.11 days in, 65.7% of the lifetime, 30.89 days before expiry
Retry-After: 25265 seconds

Your dates will differ, and so will the Retry-After value, which changed from request to request. I ran it against 32 technical sites that I picked by hand on October 12 at around 10:30 UTC, so this is not a random sample. One timed out, 18 of the 31 certificates I could read came from Let’s Encrypt, and all 18 got the same window. It opens 59.11 days after the certificate’s notBefore date, which is 65.7 percent of the lifetime, and it lasts 43.2 hours, which is 2 percent of 90 days. The window is centered on day 60, the two-thirds point, which matches Let’s Encrypt’s advice to renew “at approximately two thirds of the way through the current certificate’s lifetime.” Retry-After was 22,147 seconds on one request and 25,265 on another, so a client that polls on that cadence checks three or four times a day.

One of the 18 certificates was 85 days into its 90, with 4.9 days left and a window that had opened 26 days earlier. The probe cannot say why. It could be a stuck renewal, a deliberately late schedule or an older certificate on one node of a pool. A schedule that waits until day 80 is the kind that cannot work at 64 days, though a rule such as “10 days left” would still fire, on day 54.

What I could not test

I could not observe a 64-day certificate. Staging starts issuing them on October 14 and production on February 10, and requesting one needs an ACME account and a validated domain, which I did not create for this piece. If the window stays at two thirds of the lifetime, it would open near day 42 for a 64-day certificate. That is an extrapolation from the 90-day result, not a measurement.

Monitoring: the alert that survives 64 days with 1.3 days to spare

Alerts carry the same hidden assumption. The popular awesome-prometheus-alerts collection, which has about 8,200 stars on GitHub, ships blackbox exporter rules in its rules file, a warning for “SSL certificate expires in less than 20 days” and a critical alert for “SSL certificate expires in less than 3 days” (the descriptions as written there). The table shows how often those thresholds fire on healthy renewals when a certificate is renewed at two thirds of its lifetime, or at half for the 160-hour profile, as Certbot does.

Certificate lifetime Days left at a healthy renewal Share of each cycle under the 20-day warning Share under the 3-day critical alert
90 days 30.0 0% 0%
64 days 21.3 0% 0%
45 days 15.0 16.7% 0%
160 hours 3.3 100% 0%

At 64 days the warning stays quiet as long as renewals land within 1.3 days of the two-thirds point. At 45 days a healthy certificate trips it for the last five days of every cycle, and at 160 hours it never clears. So the rule keeps working as a failure alarm in 2027 and turns into noise in 2028. Let’s Encrypt’s December post already asks for the replacement: “We also recommend that you make sure your systems have sufficient monitoring in place to alert appropriately if certificates aren’t renewed when expected.” My suggestion, not Let’s Encrypt’s, is to alert on a renewal being overdue, measured against the lifetime or the ARI window, instead of on an absolute number of days.

Authorization reuse, and the fix that has not shipped

Let’s Encrypt will cut the authorization reuse period from 30 days to 10 on February 10, 2027 and to seven hours in 2028. The post says most subscribers can ignore it: “Unless you have specifically designed your ACME client to rely on validation reuse, you will not need to make any changes.” That fits the arithmetic. Renewals at two thirds of the lifetime land 60 days (today) or 43 days (at 64 days) after the previous validation, so each renewal already proves control again under a 30-day reuse period. The cut matters for extra orders in between, such as reissuing after adding a name or changing a key within the window. That reasoning is mine.

For people who validate with DNS-01 and cannot automate their DNS, the cost is more frequent proof of control. Let’s Encrypt said so itself: “Reducing certificate lifetimes and the authorization reuse period will make users need to demonstrate control more often.” Its answer was a new challenge type, DNS-PERSIST-01, which keeps one TXT record in place across renewals. The December post said “We expect DNS-PERSIST-01 to be available in 2026,” and the February 18 post gave dates: “Staging rollout is planned for late Q1 2026, with a production rollout targeted for some time in Q2 2026.”

That schedule slipped. On June 25, a reply in Let’s Encrypt’s community forum from the account aarongable, whose name matches RFC 9773’s ISRG author, said the company would not deploy dns-persist-01 until issue 64 in the IETF draft repository was resolved. The issue is titled “Record should include client-computed information” and GitHub shows it closed on September 23. The IETF datatracker lists revision 02 of the draft, dated September 20. Let’s Encrypt’s October 7 post does not mention DNS-PERSIST-01, and I found no production date from Let’s Encrypt as of October 12. I read the blog and searched the community forum. I did not check the technical updates mailing list.

Google Trust Services has moved first. Its September 28 announcement says “Google Trust Services now supports the dns-persist-01 challenge type for Automated Certificate Management Environment (ACME) domain validation.” It adds the caveat that “The DNS-PERSIST-01 challenge is not fully standardized” and says it implements draft version 01, not the newer revision. So a subscriber who needs persistent DNS validation can use it with Google’s CA today and with Let’s Encrypt only when Let’s Encrypt ships it. The reuse cuts are on a published schedule, and the relief for them is not.

A checklist before February

  1. After October 14, run a 64-day issuance in Let’s Encrypt’s staging environment through the whole path, including the reload or deploy hook, as the post recommends.
  2. Search cron jobs, wrapper scripts and runbooks for 60, 80 and 83, as the post suggests, and add any monitor with an absolute day threshold to the same search.
  3. Check the client. Certbot 4.0.0 or later, cert-manager and CertMagic renew by fraction by default. Anything hand-written needs a lifetime-relative rule or ARI.
  4. Rebase alerts on an overdue renewal instead of an absolute number of days.
  5. Before opting into the tlsserver profile early, read its limits on the profiles page: 25 names instead of 100, and no Common Name, Key Encipherment key usage or Subject Key ID.
  6. If DNS-01 validation cannot be automated, plan for the reuse cuts now, because Let’s Encrypt has no persistent-DNS method available yet.

The bottom line

The February 10 change is smaller than it sounds for anyone whose client renews by fraction or follows ARI, and larger than it sounds for anyone whose renewal logic is a number someone typed years ago. Let’s Encrypt chose 64 days as a stage, not because the Forum required it, and that makes February 2027 the first test of whether automation was written for 90 days or for any lifetime. The number worth finding first is the largest renewal age hard-coded anywhere in your estate. At 64 days an age of 64 or more can never fire before expiry, and 60 leaves four days.

Our report on the country-code domain hijacks that led to certificates for Google’s names is a recent example of the mis-issuance risk Let’s Encrypt cites, and our tutorial on building a private certificate authority and enforcing mutual TLS in Python shows what expiry and revocation look like in a working lab.

Sources and method

I read Let’s Encrypt’s October 7 and December 2, 2025 posts, its profiles page and its ARI integration guide, RFC 9773, the Baseline Requirements text on the CA/Browser Forum’s GitHub (version 2.3.1), the Certbot documentation, the cert-manager and CertMagic source, the awesome-prometheus-alerts rules file, Let’s Encrypt’s February 18 DNS-PERSIST-01 post and community forum thread, issue 64 in the IETF draft repository, the datatracker record and Google’s September 28 announcement. Every quotation was checked against the fetched text. The probe ran on October 12, 2026 from one machine against 32 sites I chose, using the script printed above. The renewal and alert tables are my own arithmetic from the stated lifetimes, with a day taken as 24 hours and renewals happening exactly at two thirds of the lifetime, or at half for 160 hours. I did not create an ACME account, request a certificate or test any client.

Tags:

ACMECertificate ManagementLet’s EncryptPKITLS

Share

Aerial view of a worn dirt desire line cutting straight across a hillside beside a curving paved trail
Previous Post

Attackers Probed a CVSS 10 SonicWall SMA1000 Flaw Two Days After Its Patch, the Third Such Fix in 12 Weeks

Two climbers in helmets and backpacks walk up a snow slope, joined by a taut rope between them
Next Post

How to Replace asyncio.gather With TaskGroup in Python and Handle Failures With except*

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Latest
12 Oct
How to Replace asyncio.gather With TaskGroup in Python and Handle Failures With except*
12 Oct
Let’s Encrypt’s 64-Day Default Turns Hard-Coded Renewal Numbers Into a Deadline
Trending
October 12, 2026
How to Replace asyncio.gather With TaskGroup in Python and Handle Failures With except*
October 12, 2026
Let’s Encrypt’s 64-Day Default Turns Hard-Coded Renewal Numbers Into a Deadline
October 12, 2026
Attackers Probed a CVSS 10 SonicWall SMA1000 Flaw Two Days After Its Patch, the Third Such Fix in 12 Weeks
October 11, 2026
How to Find and Fix a Memory Leak in a Python Service With tracemalloc
October 11, 2026
Ai2’s GPU Scheduler Turns Priority Into a Budget, but Leaves the Preemption Bill Unreported
October 11, 2026
Booz Allen Says Frontier AI Met All Eight Attack Goals in Its OT Lab, With a Human Approving Every Exploit

Related Posts

Blue-lit server racks in a modern data center, illustrating the compute infrastructure behind the AI boom.
Articles

The AI Boom Is Spending Real Money Before Proving Real Returns

June 7, 2026
Technician working with a laptop beside server racks, representing enterprise AI retrieval infrastructure
Articles

Google’s Agentic RAG Push Makes Enterprise AI Less of a One-Shot Guess

June 7, 2026
A person with a laptop and smartphone, representing digital attention and AI-assisted work
Articles

AI Chatbots Are Making Attention a Design Problem

June 7, 2026
A customer-support representative wearing a headset against a dark studio background.
Articles

The Meta AI Support Hack Was a Plain Old Authorization Failure

June 7, 2026
SXZ.io SXZ.io
  • [email protected]

Categories

Articles
Learning Hub
News

All Rights Reserved by SXZ.io ©2026