Let’s Encrypt 45-Day Certificates: Fix Your Linux Renewal Automation Now

On May 13, 2026, Let’s Encrypt activated its new tlsserver ACME profile — and it issues 45-day certificates. That date is not a warning. It is not a roadmap item. It has already happened. If your Linux server uses Certbot, acme.sh, or any ACME client to renew Let’s Encrypt 45 day certificates, your renewal cycle just got twice as frequent. Beyond that, authorization reuse windows are shrinking from 30 days to 7 hours by 2028, six-day short-lived certificates are now generally available, and a new DNS-PERSIST-01 validation method is rolling out this year. This post covers exactly what changed, how to verify your Certbot automation handles it, how to fix common failure modes before they take down your sites, and how to set up monitoring so silent renewal failures surface before expiry notices do.

Let's Encrypt 45 day certificate Linux SSL TLS renewal automation guide
Let’s Encrypt activated the 45-day tlsserver ACME profile on May 13, 2026. The full rollout continues through 2028, but if you opted into early testing or use automation that hits the tlsserver profile, shorter lifetimes are already in effect on your server.

What Changed and When

The shift to shorter certificate lifetimes is a multi-stage rollout, not a single cutover. Understanding the timeline prevents you from over-reacting now and under-reacting later. Here is the complete schedule as confirmed by Let’s Encrypt:

Date Change Who Is Affected
Jan 15, 2026 6-day short-lived certs now GA Opt-in only
May 13, 2026 tlsserver profile issues 45-day certs Opt-in / early adopters
Feb 10, 2027 Default classic profile switches to 64-day certs All users who have not opted in
Feb 16, 2028 Classic profile fully moves to 45-day certs + 7-hour auth reuse All users

So why act now rather than waiting until 2027 or 2028? Because silent automation failures are the real risk. A renewal system that works fine on 90-day cycles may still break silently when the same certificate arrives with a 45-day or 64-day validity. Auditing and testing your pipeline now — before the default switches — means you find the failure on your schedule, not when a certificate expires unexpectedly in production.

Let's Encrypt 45 day Certbot nginx Apache Linux server certificate renewal
With 45-day certificates, your Certbot or acme.sh renewal runs twice as often. Because most ACME clients trigger renewal at the 2/3 mark, a 45-day cert renews around day 30 — roughly every month instead of every two months.

Step 1: Check Your Current Certbot Setup

Before making any changes, audit what you currently have. Run these commands on every Linux server that serves HTTPS traffic:

# Check Certbot version -- must be recent for ARI support
certbot --version

# List all certificates and their expiry dates
certbot certificates

# Check which ACME profile your client is using
cat /etc/letsencrypt/renewal/*.conf | grep -E 'server|preferred_challenges|authenticator'

# Check the renewal timer is active (systemd)
systemctl status certbot.timer
systemctl list-timers | grep certbot

# Verify the renewal hook runs correctly (dry run)
certbot renew --dry-run

# Check when certificates were last renewed
ls -la /etc/letsencrypt/live/
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/cert.pem -noout -dates

The dry run output is the most important check. If it shows any errors, those errors will also cause real renewals to fail silently — except you won’t know until the certificate expires. Fix dry-run errors before proceeding.

Step 2: Update Certbot to the Latest Version

Older Certbot versions lack support for ACME Renewal Information (ARI), which allows Let’s Encrypt to dynamically signal exactly when each certificate should renew. Without ARI support, your client uses a static schedule that may not align with the shorter validity periods. Update Certbot on your distro before anything else:

# RHEL / AlmaLinux / Rocky 8 and 9 -- use snap for latest Certbot
# Remove old system package first if present
dnf remove certbot python3-certbot-nginx python3-certbot-apache -y 2>/dev/null

# Install via snap (always latest version)
dnf install snapd -y
systemctl enable --now snapd.socket
snap install core && snap refresh core
snap install --classic certbot
ln -sf /snap/bin/certbot /usr/bin/certbot
certbot --version

# Ubuntu / Debian -- also use snap for latest
apt remove certbot python3-certbot-nginx python3-certbot-apache -y 2>/dev/null
snap install --classic certbot
ln -sf /snap/bin/certbot /usr/bin/certbot
certbot --version

After updating, run a dry-run renewal to confirm the new version works correctly with your existing certificates:

certbot renew --dry-run --verbose 2>&1 | tail -30

Step 3: Verify Your nginx or Apache Reload Hook

Renewing a certificate is only half the job. Because nginx and Apache serve the old certificate until they reload their config, your deploy hook must reload the web server after every successful renewal. Without the hook, your server keeps serving the expired cert even though the new one is on disk. Check that the hook exists and is correct:

# Check existing deploy hooks
ls -la /etc/letsencrypt/renewal-hooks/deploy/
cat /etc/letsencrypt/renewal-hooks/deploy/*.sh 2>/dev/null

# If no hook exists for nginx, create one:
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh << 'HOOKEOF'
#!/bin/bash
nginx -t && systemctl reload nginx
HOOKEOF
chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

# For Apache instead:
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh << 'HOOKEOF'
#!/bin/bash
apachectl configtest && systemctl reload httpd 2>/dev/null || systemctl reload apache2
HOOKEOF
chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh

# Test the hook fires correctly on dry-run
certbot renew --dry-run --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

For nginx reverse proxy setups, also verify the certificate path inside your server block matches what Certbot writes. Our nginx reverse proxy setup guide covers the full TLS configuration for proxy environments where the certificate may need distributing to multiple upstream blocks.

Let's Encrypt 45 day certificate ACME DNS challenge automation Linux
The DNS-01 challenge is the most flexible ACME validation method. Unlike HTTP-01, it works for wildcard certificates and servers not exposed to the internet. With the 7-hour authorization reuse window coming in 2028, DNS-01 with API automation is the only practical path for high-frequency renewals.

Step 4: Switch to DNS-01 Challenge for Wildcards and Internal Servers

If you manage wildcard certificates or servers without public HTTP access, the HTTP-01 challenge cannot work for you. In that case, DNS-01 is the correct path. Since the authorization reuse window shrinks to 7 hours in 2028, DNS-01 with automated API updates also becomes the only practical option for high-frequency renewals. Here is how to configure it for the most common DNS providers:

# Install the DNS plugin for your provider
# Cloudflare:
snap install certbot-dns-cloudflare 2>/dev/null || \
  pip3 install certbot-dns-cloudflare --quiet

# Create Cloudflare API token credentials file
cat > /etc/letsencrypt/cloudflare.ini << 'CFEOF'
# Cloudflare API token -- create at dash.cloudflare.com with Zone:DNS:Edit permission
dns_cloudflare_api_token = YOUR_API_TOKEN_HERE
CFEOF
chmod 600 /etc/letsencrypt/cloudflare.ini

# Issue wildcard certificate using DNS-01
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 30 \
  -d 'yourdomain.com' \
  -d '*.yourdomain.com'

# For Route53 (AWS):
pip3 install certbot-dns-route53 --quiet
certbot certonly --dns-route53 -d 'yourdomain.com' -d '*.yourdomain.com'

# For DigitalOcean:
pip3 install certbot-dns-digitalocean --quiet
certbot certonly \
  --dns-digitalocean \
  --dns-digitalocean-credentials /etc/letsencrypt/digitalocean.ini \
  -d 'yourdomain.com' -d '*.yourdomain.com'

Step 5: Harden the Renewal Timer and Frequency

With 45-day certificates, renewal needs to happen roughly every 30 days (since Certbot triggers at the two-thirds validity mark). However, the default systemd timer runs only twice per day. That is still fine for standard renewals, but it means a failure detected at the morning run has until the evening run before it retries. For tighter coverage, confirm the timer is running and consider adding a weekly explicit check:

# Verify the certbot systemd timer is active
systemctl is-active certbot.timer
systemctl status certbot.timer

# If the timer is missing, create it (common on RHEL after snap install)
cat > /etc/systemd/system/certbot.service << 'SVCEOF'
[Unit]
Description=Certbot Renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet
PrivateTmp=true
SVCEOF

cat > /etc/systemd/system/certbot.timer << 'TIMEREOF'
[Unit]
Description=Run Certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target
TIMEREOF

systemctl daemon-reload
systemctl enable --now certbot.timer
systemctl list-timers | grep certbot
Let's Encrypt 45 day certificate renewal monitoring alert Linux sysadmin
Certificate expiry monitoring must run independently of your renewal automation. If Certbot is broken, it cannot alert you that it is broken. An external check catches silent failures before users see a certificate warning.

Step 6: Set Up Certificate Expiry Monitoring

Automation failures are often silent. Because Certbot does not alert you when it fails — it just logs to journald and moves on — independent expiry monitoring is essential. Here is a lightweight bash script that checks every certificate on the system and sends an alert when any cert has fewer than 15 days remaining:

cat > /usr/local/sbin/cert-check.sh << 'CERTEOF'
#!/bin/bash
# Certificate expiry monitor -- runs daily via cron
WARN_DAYS=15
ALERT_EMAIL=admin@yourdomain.com
ERRORS=''

for domain_dir in /etc/letsencrypt/live/*/; do
  domain=$(basename $domain_dir)
  cert=$domain_dir/cert.pem
  [ -f '$cert' ] || continue

  expiry=$(openssl x509 -in $cert -noout -enddate 2>/dev/null | cut -d= -f2)
  expiry_epoch=$(date -d '$expiry' +%s 2>/dev/null)
  now_epoch=$(date +%s)
  days_left=$(( (expiry_epoch - now_epoch) / 86400 ))

  if [ $days_left -lt $WARN_DAYS ]; then
    ERRORS+='EXPIRING SOON: '$domain' -- '$days_left' days left (expires '$expiry')'
    ERRORS+=$'\n'
  fi
done

if [ -n '$ERRORS' ]; then
  echo -e 'Certificate expiry warning:\n\n$ERRORS' | \
    mail -s 'CERT EXPIRY WARNING on '$HOSTNAME $ALERT_EMAIL
  echo "$ERRORS"
  exit 1
fi
echo 'All certificates OK'
CERTEOF
chmod 755 /usr/local/sbin/cert-check.sh

# Add daily cron job
echo '0 8 * * * root /usr/local/sbin/cert-check.sh >> /var/log/cert-check.log 2>&1' \
  > /etc/cron.d/cert-check

# Test it immediately
/usr/local/sbin/cert-check.sh

Beyond local monitoring, also verify certificates from the outside using openssl s_client. This catches cases where the certificate renewed on disk but the web server never reloaded and is still serving the old one:

# Check what certificate is actually being served over the network
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
  | openssl x509 -noout -dates -subject

# Automate the external check for multiple domains
for domain in yourdomain.com api.yourdomain.com mail.yourdomain.com; do
  expiry=$(echo | openssl s_client -connect $domain:443 -servername $domain 2>/dev/null \
    | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
  echo "$domain: $expiry"
done

The New Short-Lived and IP Address Certificates

Beyond the 45-day transition, Let's Encrypt made two additional changes in January 2026 that are worth understanding even if you do not use them immediately.

Six-day certificates are now generally available via the shortlived ACME profile. Because the validity window is only 160 hours, these certificates require fully automated renewal with zero manual steps. For teams whose automation is already solid, they offer a significant security benefit: if a private key is compromised, the damage window is six days instead of 45 or 90. To opt in, set the certificate profile in your Certbot renewal config:

# Opt into 6-day certificates on an existing cert
# Edit the renewal config file for your domain
cat /etc/letsencrypt/renewal/yourdomain.com.conf

# Add or update the server profile line:
# Under [renewalparams]:
# certificate_profile = shortlived

# Or re-issue with the profile flag:
certbot certonly \
  --cert-name yourdomain.com \
  --certificate-profile shortlived \
  --force-renewal

# Verify the new expiry is ~6 days
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/cert.pem \
  -noout -dates

IP address certificates are also now available from Let's Encrypt, but only as short-lived certificates. This is useful for securing direct IP connections to internal services, load balancers that terminate TLS before a hostname is resolved, or monitoring tools that connect by IP rather than DNS name. Since IP addresses are more transient than domain names, the short-lived requirement makes sense — frequent revalidation ensures the IP is still under your control.

Let's Encrypt 45 day cert short lived 6 day IP certificate Linux automation
Six-day certificates and IP address certificates from Let's Encrypt are now generally available. Both require fully automated renewal pipelines — there is no practical way to manage either manually.

Common Renewal Failure Modes and How to Fix Them

With more frequent renewals, the same automation weaknesses that existed before now surface more often. Here are the most common failure patterns along with their fixes:

Failure Mode Symptom Fix
Certbot Python env broken after OS upgrade Renewal silently fails, no new cert issued Reinstall via snap to get isolated Python env
DNS API key rotated, DNS-01 fails Challenge fails, cert not renewed Update credentials file, test with --dry-run
Port 80 blocked by firewall HTTP-01 challenge times out Open port 80 or switch to DNS-01
nginx not reloaded after renewal New cert on disk, old cert served Add deploy hook to reload nginx
Rate limit hit from too many requests Renewal fails with 429 error Spread renewals with RandomizedDelaySec in timer
Certificate renewed but not deployed to CDN Origin renewed, CDN still serves old cert Add CDN API call to deploy hook

Security Hardening Around Certificate Management

Because Let's Encrypt certificates are free and automated, they are sometimes treated as a lower-security category than paid certificates. In practice, the cryptographic strength is identical. However, the automation around them introduces its own attack surface that deserves hardening. Apply these practices on every server that runs Certbot:

# Verify certificate file permissions are correct
ls -la /etc/letsencrypt/live/yourdomain.com/
# privkey.pem should be readable only by root (or the service user)
chmod 600 /etc/letsencrypt/live/yourdomain.com/privkey.pem

# Verify the DNS credentials file is not world-readable
ls -la /etc/letsencrypt/*.ini 2>/dev/null
chmod 600 /etc/letsencrypt/*.ini 2>/dev/null

# Confirm nginx is not running as root
ps aux | grep nginx | grep -v grep | awk '{print $1}' | sort -u
# worker processes should show as 'nginx' or 'www-data', not root

# Check TLS configuration quality
# Ensure TLSv1.0 and TLSv1.1 are disabled in nginx
grep ssl_protocols /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf 2>/dev/null
# Should show: ssl_protocols TLSv1.2 TLSv1.3;

Our Linux server hardening checklist covers the full TLS hardening baseline, including cipher suite configuration, HSTS headers, and OCSP stapling settings that complement the certificate management steps above.

Conclusion

The Let's Encrypt 45-day certificate rollout is already underway on Linux servers. While the default profile does not switch until February 2027, testing and fixing your automation now means you control the timing rather than reacting to an expiry notice. Start by running certbot renew --dry-run on every server today. After that, confirm your deploy hooks reload nginx or Apache after renewal. Then add independent expiry monitoring so silent failures surface before they affect users. If you manage wildcard certificates or internal servers, migrate to DNS-01 before the authorization reuse window shrinks in 2028. Finally, consider whether six-day short-lived certificates make sense for your highest-value domains — if your automation is solid, the dramatically shorter compromise window is a genuine security improvement. The full Let's Encrypt announcement and migration timeline are at letsencrypt.org, with additional analysis from GBHackers.

}