Short answer. CA/Browser Forum ballot SC-081, adopted on 11 April 2025, cuts the maximum validity of publicly trusted TLS certificates in three steps. Certificates issued from 15 March 2026 may last up to 200 days, from 15 March 2027 up to 100 days, and from 15 March 2029 up to 47 days. The time a CA may reuse a domain validation shrinks on the same dates: 200 days, then 100, then 10. In practice every certificate has to be issued and deployed by automation (ACME). Renewal should follow the CA's ARI window, and you need monitoring that alerts you while there is still time to fix a broken renewal. Private CAs are not affected.
The schedule
The rules live in sections 6.3.2 and 4.2.1 of the Baseline Requirements (version 2.3.1, October 2026). Ballot SC-081v3 was proposed by Apple and endorsed by Sectigo, Google Chrome and Mozilla. It passed with 25 CA votes in favour, none against and 5 abstentions, and all four browser vendors voted yes.
| Certificate issued | Maximum validity | Domain/IP validation reuse | Organization identity reuse |
|---|---|---|---|
| before 15 March 2026 | 398 days | 398 days | 825 days |
| 15 March 2026 to 14 March 2027 | 200 days | 200 days | 398 days |
| 15 March 2027 to 14 March 2029 | 100 days | 100 days | 398 days |
| from 15 March 2029 | 47 days | 10 days | 398 days |
Some details that matter when you plan around these numbers:
- The limits are upper bounds that CAs enforce at issuance. A certificate issued on 14 March 2026 could still be valid for 398 days. Nothing forces you to replace it before it expires, but its replacement will be short.
- "Validity" counts both ends. The BR defines it as the period from
notBeforethroughnotAfterinclusive, and it recommends one day of headroom: certificates "SHOULD NOT" exceed 199, 99 and 46 days. - The validation reuse limit is the bigger change. Today a CA can reuse proof that you control
example.comfor months. From 2029 the proof must be at most 10 days old, so almost every issuance needs a fresh domain validation, and the DNS or HTTP challenge has to be automated too. - Organization details in OV and EV certificates (company name, address) may be reused for 398 days instead of 825.
- Scope. The BR governs TLS server certificates from publicly trusted CAs. Certificates from your own internal CA, client certificates and S/MIME certificates fall under other rules or none.
What CAs issue today
On 20 October 2026, the certificates served by a few large sites looked like this. The output comes from the
lifetimes.sh script in the monitoring section:
letsencrypt.org Let's Encrypt 2026-09-04 -> 2026-12-03 (90 days)
www.google.com Google Trust Services 2026-09-28 -> 2026-12-21 (84 days)
github.com Sectigo Limited 2026-09-01 -> 2026-11-29 (90 days)
www.microsoft.com Microsoft Corporation 2026-01-22 -> 2027-01-17 (360 days)
www.amazon.com Amazon 2026-01-19 -> 2027-01-11 (358 days)
www.digicert.com DigiCert Inc 2026-10-11 -> 2026-11-26 (47 days)
Two of them still carry certificates of almost a year, issued in January 2026, just before the 200-day limit took effect. DigiCert already serves a 47-day certificate on its own site. Let's Encrypt's published plan moves faster than the BR requires:
- 13 May 2026: the opt-in
tlsserverprofile issues 45-day certificates. - 10 February 2027: the default
classicprofile issues 64-day certificates with a 10-day authorization reuse period. - 16 February 2028:
classicissues 45-day certificates with a 7-hour authorization reuse period.
The live ACME directory lists the profiles you can request today:
"meta": {
"profiles": {
"classic": "https://letsencrypt.org/docs/profiles#classic",
"shortlived": "https://letsencrypt.org/docs/profiles#shortlived",
"tlsserver": "https://letsencrypt.org/docs/profiles#tlsserver"
}
},
"renewalInfo": "https://acme-v02.api.letsencrypt.org/acme/renewal-info"
What to automate
With 398-day certificates, a manual yearly renewal was annoying but survivable. With 47-day certificates and 10-day validation reuse, manual renewal is an error-prone task at least eight times a year for every name, and closer to twelve if you renew at two thirds of the lifetime. The work splits into four parts.
1. Issuance through ACME. Use an ACME client (RFC 8555) for every certificate from a public CA. Most commercial CAs offer ACME endpoints too, often with external account binding. If a certificate still arrives by email, a portal download or a ticket, put it on the list first.
2. Validation that runs unattended. Choose a challenge that works without a person:
http-01needs port 80 reachable on every host that serves the name.dns-01needs API access to your DNS provider. Scope the token to_acme-challengerecords where the provider allows it.tls-alpn-01runs entirely on port 443.
Two newer methods are written for exactly this situation. "DNS Labeled with Account ID", the ACME
dns-account-01 challenge in BR §3.2.2.4.21, lets several ACME accounts validate the same name without fighting
over one _acme-challenge record. "DNS TXT Record with Persistent Value" (§3.2.2.4.22, ballot SC-088) lets you
publish a standing record once:
_validation-persist.example.com IN TXT "authority.example; accounturi=https://authority.example/acct/123; persistUntil=1782424856"
The CA may treat each check of that record as good for at most 10 days. It re-checks the record itself, though, so nobody has to touch DNS for each renewal. Ask your CA whether it supports the method before you rely on it.
3. Renewal that follows the CA. Renew early and let the CA steer the timing:
- Renew at about two thirds of the lifetime. That is day 30 of a 45-day certificate. Let's Encrypt states that "renewing at a hardcoded interval of 60 days will no longer be sufficient." Since version 4.0, certbot renews with a third of the lifetime left instead of at a fixed 30 days.
- Use ARI (RFC 9773), covered in the next section. The CA tells each client when to renew, and it can pull that window forward when it has to revoke certificates in bulk.
- Request the profile explicitly if you want 45-day certificates before your CA's default changes.
4. Deployment to every copy. Renewing the file on disk is not the end. List every place a certificate is copied to:
- load balancers and CDNs that take uploaded certificates,
- Kubernetes secrets,
- Java keystores and PKCS#12 bundles,
- appliances, mail servers, databases and message brokers,
- mobile apps that pin a leaf certificate.
Each copy needs either a reload hook or an integration that fetches the new certificate. Pinning a leaf certificate or its key in an app becomes unworkable at this cadence. Pin a CA key instead, or better, don't pin.
This test runs certbot 5.8.0 against a local Pebble 2.10.1 ACME server
whose tlsserver profile issues 45-day certificates. It shows that the profile request and the renewal
configuration work as documented:
$ certbot certonly --standalone --non-interactive --agree-tos --register-unsafely-without-email \
--server https://localhost:14000/dir -d app.example.test --preferred-profile tlsserver
Account registered.
Requesting a certificate for app.example.test
Successfully received certificate.
This certificate expires on 2026-12-04.
$ openssl x509 -in /etc/letsencrypt/live/app.example.test/cert.pem -noout -startdate -enddate
notBefore=Oct 20 11:47:52 2026 GMT
notAfter=Dec 4 11:47:51 2026 GMT
$ grep -E "preferred_profile|server" /etc/letsencrypt/renewal/app.example.test.conf
preferred_profile = tlsserver
server = https://localhost:14000/dir
$ certbot renew --non-interactive
Processing /etc/letsencrypt/renewal/app.example.test.conf
Certificate not yet due for renewal
certbot stores the profile in the renewal configuration, so every later renewal asks for it again. The
--preferred-profile flag exists since certbot 4.0. If the CA's directory does not list the named profile, it
falls back to the CA's default. --required-profile makes issuance or renewal fail instead. Profiles come from
draft-ietf-acme-profiles, which was waiting for
IESG review in October 2026. Clients other than certbot have their own flag names.
ACME Renewal Information (ARI)
ARI (RFC 9773, June 2025) turns renewal timing from a client-side guess into a question to the CA. For each certificate, the client builds an identifier from the certificate's Authority Key Identifier and serial number:
url = renewalInfo || '/' || base64url(AKI keyIdentifier) || '.' || base64url(Serial)
It then polls that URL without authentication. The response holds a suggestedWindow, and a Retry-After
header says when to ask again. You can query it yourself for any Let's Encrypt certificate:
#!/bin/bash
set -e
host="$1"
openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null | openssl x509 -out cert.pem
aki=$(openssl x509 -in cert.pem -noout -ext authorityKeyIdentifier | grep -o -E '([0-9A-F]{2}:){19}[0-9A-F]{2}' | tr -d ':')
serial=$(openssl x509 -in cert.pem -noout -serial | cut -d= -f2)
# The DER INTEGER content keeps a leading 00 byte when the high bit is set.
[ $(( 16#${serial:0:1} )) -ge 8 ] && serial="00$serial"
b64url() { python3 -c 'import sys,base64; print(base64.urlsafe_b64encode(bytes.fromhex(sys.stdin.read().strip())).decode().rstrip("="))'; }
id="$(printf %s "$aki" | b64url).$(printf %s "$serial" | b64url)"
ari=$(curl -s https://acme-v02.api.letsencrypt.org/directory | grep -o '"renewalInfo": *"[^"]*"' | cut -d'"' -f4)
openssl x509 -in cert.pem -noout -issuer -startdate -enddate
echo "GET $ari/$id"
curl -s -D - "$ari/$id" | grep -i -E '^retry-after|^\{|"'
issuer=C=US, O=Let's Encrypt, CN=YE2
notBefore=Sep 4 14:34:32 2026 GMT
notAfter=Dec 3 14:34:31 2026 GMT
GET https://acme-v02.api.letsencrypt.org/acme/renewal-info/uVnyjs8i8IbTN0j_dhQYuoLYVYc.BUOTO-OGs6KzrdU08hA7yLZf
retry-after: 25769
{
"suggestedWindow": {
"start": "2026-11-02T17:18:36Z",
"end": "2026-11-04T12:29:25Z"
The window opens 59 days into this 90-day certificate, at about two thirds of its lifetime. The client should
pick a random moment inside the window, which spreads renewals over time. If the CA has to revoke certificates
in bulk, it moves the window into the past, and well-behaved clients renew within hours instead of failing at
expiry. When renewing, the client sends the old certificate's identifier in the replaces field of its new
order.
ARI support in common clients, from their release notes:
| Client | ARI since | Notes |
|---|---|---|
| certbot | 4.1.0 (June 2025) | On by default in certbot renew. 5.0 stores Retry-After across runs |
| Caddy | 2.8.0 (May 2024) | Built in through CertMagic |
| lego | 4.12.0 (May 2023) | First implementation. The identifier format was updated as the draft changed |
| acme.sh | 3.1.4 (July 2026) | On by default. NO_ARI=1 disables it. The cron job now runs every 6 hours |
| cert-manager | 1.21.0 (July 2026) | Experimental, behind the ACMEUseARI feature gate |
Monitoring that catches a broken renewal
Automation fails quietly: an expired DNS API token, a firewall change that blocks port 80, a reload hook that stopped working. With a 47-day certificate renewed at day 30, you have about 17 days between the first failed renewal and an outage. Alert early in that gap.
From outside. Probe every public name, not only the ones you remember. The Prometheus
blackbox exporter exposes the expiry of the served chain as
probe_ssl_earliest_cert_expiry:
probe_ssl_earliest_cert_expiry 1.795737599e+09
probe_success 1
probe_tls_version_info{version="TLS 1.3"} 1
These two alert rules pass promtool check rules (Prometheus 3.5.0). The first fires when the renewal is
overdue, the second when an outage is close:
groups:
- name: certificates
rules:
- alert: CertificateRenewalOverdue
# Fires when less than a third of a 47-day lifetime (about 16 days) is left:
# the renewal job should have replaced the certificate by now.
expr: probe_ssl_earliest_cert_expiry - time() < 16 * 86400
for: 1h
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }}: certificate expires in {{ $value | humanizeDuration }}"
- alert: CertificateExpiresSoon
expr: probe_ssl_earliest_cert_expiry - time() < 7 * 86400
for: 10m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }}: certificate expires in {{ $value | humanizeDuration }}"
From a script. openssl x509 -checkend N exits with status 1 if the certificate expires within N seconds,
which is enough for a cron job or a CI step:
$ openssl x509 -in cert.pem -noout -enddate
notAfter=Nov 26 23:59:59 2026 GMT
$ openssl x509 -in cert.pem -noout -checkend $((30 * 86400)); echo "exit status: $?"
Certificate will not expire
exit status: 0
$ openssl x509 -in cert.pem -noout -checkend $((45 * 86400)); echo "exit status: $?"
Certificate will expire
exit status: 1
The survey table at the top of this page came from this script:
#!/bin/bash
for host in "$@"; do
openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null | openssl x509 -out /tmp/c.pem 2>/dev/null || { echo "$host: no certificate"; continue; }
nb=$(openssl x509 -in /tmp/c.pem -noout -startdate | cut -d= -f2)
na=$(openssl x509 -in /tmp/c.pem -noout -enddate | cut -d= -f2)
issuer=$(openssl x509 -in /tmp/c.pem -noout -issuer -nameopt multiline | grep -E "organizationName" | head -1 | cut -d= -f2 | sed 's/^ *//')
days=$(( ($(date -d "$na" +%s) - $(date -d "$nb" +%s) + 1) / 86400 ))
printf '%-22s %-26s %s -> %s (%s days)\n' "$host" "$issuer" "$(date -u -d "$nb" +%F)" "$(date -u -d "$na" +%F)" "$days"
done
From the CA's side. Certificate Transparency logs record every certificate issued for your domains. A CT monitor shows renewals that happened and certificates you didn't expect. See Certificate Transparency for developers, or look up a domain's history with the CT history tool. To see how ready a set of domains is, the certificate lifetime calculator works through the schedule for each certificate you have.
CAA and account binding
Shorter validation reuse means more validations, and each one checks your
CAA records. From 15 March 2027 (ballot SC-098), CAs must also
honour the accounturi and validationmethods parameters from RFC 8657.
That lets you limit issuance to your own ACME account and your chosen challenge type:
example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789; validationmethods=dns-01"
The CAA record generator builds these records. Keep in mind that a stale CAA record will block your own renewals, which now happen at least eight times a year instead of once.
Common mistakes
- A fixed renewal interval. "Renew every 60 days" already fails for 45-day certificates. Renew on a fraction of the lifetime, or on ARI.
- Renewing without reloading. The new file sits on disk while the server keeps serving the old certificate from memory until it expires. Test the deploy hook, not just the renewal.
- Forgetting the copies. The origin renews automatically, but the CDN or load balancer still has a manually uploaded certificate.
- Alerting at 7 days. With 47-day certificates, an alert a week before expiry leaves no time to debug a DNS API or firewall problem. Alert when the renewal is overdue.
- Pinning leaf keys in mobile apps or API clients. Every renewal with a new key breaks them.
- Assuming private PKI must follow. Your internal CA can keep its own policy. Short lifetimes are still a good idea there, but they are your choice.
Sources
- CA/Browser Forum, Baseline Requirements v2.3.1: §1.2.2 (relevant dates), §3.2.2.4.21–22 (new DNS methods), §4.2.1 (reuse periods), §6.3.2 (validity).
- Ballot SC-081v3 (adopted 11 April 2025, effective 16 May 2025).
- RFC 9773: ACME Renewal Information. RFC 8555: ACME. draft-ietf-acme-profiles.
- Let's Encrypt, Decreasing Certificate Lifetimes to 45 Days and profiles.
- Release notes of certbot, Caddy, lego, acme.sh and cert-manager.
- RFC 8659 (CAA) and RFC 8657
(CAA
accounturiandvalidationmethods).
Command output was produced on 20 October 2026 in node:24.22.0-trixie (OpenSSL 3.5.7, curl 8.14.1),
certbot/certbot:v5.8.0 with ghcr.io/letsencrypt/pebble:2.10.1,
quay.io/prometheus/blackbox-exporter:v0.25.0 and prom/prometheus:v3.5.0.