Skip to main content

Let's Encrypt Is Ending Expiry Emails and OCSP: What to Replace Before June

Let's Encrypt will stop sending expiration emails and is winding down OCSP in 2025. What that removes from your safety net, and what to put in its place.

The CompleteStatus Team 7 min read

Let's Encrypt Is Ending Expiry Emails and OCSP: What to Replace Before June

Want this checked continuously?

CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.

Monitor your site free

Two changes from Let's Encrypt this year look like housekeeping, and for most sites they are. But one of them quietly removes a safety net a lot of teams didn't know they were relying on, and the other can break software that assumed a feature would always be there. Both have dates attached, and the first one is less than three months away.

Change one: no more expiration emails

In January, Let's Encrypt announced it would stop sending certificate expiration notification emails, with the service ending on June 4, 2025. Those are the messages that arrive about three weeks before a certificate expires if it hasn't been renewed: "Let's Encrypt certificate expiration notice for domain example.com".

Their stated reasons are reasonable. Most ACME clients renew automatically, so the emails mostly go to people who don't need them. Running the service costs real money for a nonprofit. And keeping millions of email addresses tied to certificate issuance is a privacy liability they would rather not hold. Along with ending the emails, they said they would delete the addresses they have on file.

The catch: for a lot of small teams, that email was the monitoring. Nobody set it up on purpose. Someone typed an address into certbot years ago, and ever since, when renewal broke, a warning showed up in an inbox with weeks to spare. It was a free, independent check that sat outside your renewal pipeline, which is exactly the property good monitoring needs.

After June 4, when your renewal silently stops, the first notice you get will be the browser warning your visitors see.

Who is actually exposed

You're fine if something else already watches the certificate your servers are serving. You're exposed if any of these are true:

  • The only alert you have ever received about a certificate came from Let's Encrypt.
  • Renewal runs from a cron entry or systemd timer that nobody has looked at since the server was built.
  • You have certificates on hosts outside your main deployment path: a mail server, a VPN endpoint, an old admin panel, a staging box that became production.
  • Certificates are issued on one machine and copied to others (load balancers, appliances), so "renewed" and "deployed" are two separate steps.

We wrote about the ways 90-day renewal automation fails quietly a few years ago. None of those failure modes went away. What's going away is the thing that used to catch them.

What to replace it with

Something that checks the live endpoint, not the renewal log. A cron job that confirms certbot ran is not enough, because the classic failure is a renewal that succeeded on disk while nginx kept serving the old certificate.

The minimum version is a script you can run today:

#!/bin/sh
# warn if the certificate served on :443 expires within 21 days
host="$1"
end=$(echo | openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null \
  | openssl x509 -noout -enddate | cut -d= -f2)
if ! echo | openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null \
  | openssl x509 -noout -checkend $((21*86400)) >/dev/null; then
  echo "WARNING: $host certificate expires $end"
fi

Run it daily for every hostname you serve TLS on, from a machine that isn't the one being checked, and make sure its output goes somewhere a human reads. Then ask the obvious question: what alerts you when that cron job stops running? This is why most teams end up with an external monitoring service for certificates rather than a script, but either is far better than nothing.

Whatever you use, alert earlier than you think you need to. With 90-day certificates and certbot's default of renewing at 30 days remaining, a certificate that drops below about 20 days means renewal has already failed more than once.

Change two: OCSP is being wound down

The second change is more technical. Let's Encrypt has said it intends to end support for OCSP (the Online Certificate Status Protocol) and rely on Certificate Revocation Lists (CRLs) instead. The published timeline, as we understand it:

  • January 30, 2025: requests for certificates with the OCSP Must-Staple extension started failing, except for accounts that had previously issued such certificates.
  • May 7, 2025: OCSP URLs will no longer be included in new certificates; CRL URLs will be.
  • August 6, 2025: the OCSP responders are scheduled to be shut down.

Check Let's Encrypt's own announcements before acting on those dates; timelines like this sometimes move.

The rationale is mostly privacy. With OCSP, a browser asking "is this certificate still valid?" tells the CA which site the user is visiting. CRLs don't leak that. Browsers have largely moved away from live OCSP checks anyway (Chrome stopped doing them by default years ago), and the CA/Browser Forum made OCSP optional for publicly trusted CAs in 2023. For ordinary browser traffic to your site, you probably won't notice anything.

Where it can bite

  • OCSP stapling configs. If your server is set to staple OCSP responses, certificates issued after May 7 won't carry an OCSP URL to fetch from. nginx and Apache should just skip stapling for those certificates, but check your error logs after the first renewal past that date rather than assuming. Some configurations log warnings on every reload.
  • Must-Staple certificates. If you requested Must-Staple, remove that option from your ACME client configuration now. A browser that honors Must-Staple will refuse the connection if no stapled response is present, which is exactly the situation once the responders go away.
  • Clients that insist on OCSP. Some older libraries, embedded devices and hardened enterprise configurations treat a missing or unreachable OCSP responder as a failure. If you run an API consumed by that kind of client, test against a certificate without an OCSP URL before May. The easy way: check what your current certificate advertises.
# which revocation endpoints does the served certificate list?
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -text | grep -A2 -E "Authority Information Access|CRL Distribution"

Today you'll likely see an OCSP - URI: line. After your first renewal past May 7, you should see a CRL distribution point instead. If something in your stack breaks at that point, it was depending on OCSP.

A checklist for the next three months

  1. List every hostname that serves a Let's Encrypt certificate, including the ones nobody thinks about. Certificate Transparency search (crt.sh) will show you certificates issued for your domains that you may have forgotten.
  2. Put an independent expiry check on each one before June 4. Alert at 20 days or earlier.
  3. Remove Must-Staple from any ACME client config that requests it.
  4. Review OCSP stapling settings and plan to read the logs after the first post-May renewal.
  5. Test your strict clients (mobile apps, partner integrations, embedded devices) against a certificate that lists CRLs but not OCSP.
  6. Stop using a personal email on your ACME account. It's about to stop mattering for expiry notices, but it still matters for policy and incident announcements.

Neither change is a crisis. Let's Encrypt gave months of notice, which is more than most dependencies do. The risk is the same one as always with certificates: a failure you hear about from a customer, because the warning you counted on was never really yours. If you already have an outside check watching your live certificates, whether that's a script, CompleteStatus or something else, June 4 is just another Wednesday.

Written with AI assistance and reviewed by the CompleteStatus team.