Back to Blog

OpenSSL 3.0 Is End of Life. Its First High-Severity Fix Is for Paying Customers Only.

OpenSSL ships a High-severity fix on September 29, 2026. The 3.0 patch goes to premium support customers only. Here's how to find every 3.0 copy you still run.

CertGuard TeamSSL Security Experts10 min read
Black-and-white view of the back of a rack server chassis, with rows of fan modules behind hexagonal grilles, black cables running across the top and four power inlets along the bottom

The patch ships Tuesday. Just not for 3.0.

On September 23, 2026 the OpenSSL project sent its usual heads-up to the openssl-announce list. Security releases 4.0.3, 3.6.5, 3.5.9 and 3.4.8 go out on Tuesday, September 29, between 13:00 and 17:00 UTC. Highest severity fixed: High.

Then comes the second paragraph. "We will also be releasing extended support for OpenSSL versions 3.0.23, 1.1.1zj, and 1.0.2zs which will be available to premium support customers."

So a 3.0.23 exists. It fixes the same bugs. You can't download it unless you pay OpenSSL Corporation. This is the first High-severity release since OpenSSL 3.0 went end of life, and it's where EOL stops being a date on a roadmap. Now it's a CVE you can't patch from upstream.

Think your fleet left 3.0 behind years ago? Check. Most fleets haven't.

What end of life actually means for 3.0

OpenSSL 3.0 shipped on September 7, 2021 as a long-term support release. LTS gets five years of public fixes, so public support ended on September 7, 2026. The project made it official in a post on September 16: 3.0 "will no longer receive publicly available security fixes." The last public 3.0 release was 3.0.22, tagged on August 25.

The security policy says a High issue "will trigger a new release of all supported versions." 3.0 isn't a supported version anymore. That one sentence is the whole problem.

We don't know what the bug is yet. The pre-announcement gives a date, a severity and nothing more. OpenSSL defines High as lower risk than Critical, "perhaps due to affecting less common configurations, affecting only protocol clients, or which are less likely to be exploitable." Maybe it never touches your nginx. Maybe it's in the HTTP client inside every service you run. Nobody outside the embargo can tell you before Tuesday afternoon, which is why you want the inventory finished before the advisory lands.

One more date for regulated shops. The FIPS 140-2 certificates for the 3.0 FIPS provider moved to the CMVP Historical List on September 21, 2026. If an auditor asks about your FIPS story, "3.0" stopped being a good answer last week.

Your distro is probably fine. Your containers probably aren't.

This is the part that keeps it from being a panic post. Most OpenSSL on most servers comes from your distribution, and distributions keep patching their own packages long after upstream walks away.

Today the package archives list:

  • Ubuntu 22.04: 3.0.2-0ubuntu1.29
  • Ubuntu 24.04: 3.0.13-0ubuntu3.15
  • Debian 12: 3.0.22-1~deb12u1
  • Debian 13: 3.5.7-1~deb13u2

Ubuntu 24.04, the current LTS, is a 3.0 system. Debian 12 too. That's fine for as long as Canonical and Debian keep backporting, and OpenSSL's policy is to pre-notify OS vendors with details and patches, usually two weeks ahead of a release. Don't expect the version string to help you, though. Ubuntu's 3.0.2 has said "3.0.2" for four years while the suffix crept up to .29. Red Hat rebased RHEL 9.5 onto OpenSSL 3.2.2, a branch upstream dropped in November 2025. A vendor's version number says nothing about upstream support. It never did.

The trouble is everything that didn't arrive through apt or dnf. That's where 3.0 stays 3.0 forever.

Where 3.0 hides

Runtimes that bundle their own copy

Official Node.js binaries link OpenSSL statically. Your distro patches libssl3 and your Node process couldn't care less. The Node.js release index shows the latest Node 20 release, v20.20.2, bundling OpenSSL 3.0.19, and Node 20 itself went end of life on April 30, 2026. Node 18's last release carries 3.0.16. Current Node 22, 24 and 26 builds ship 3.5.8. An old node:20 image is end of life stacked on end of life.

Python looks the same on Windows and macOS, where the python.org installers bundle OpenSSL. The CPython team's own tracking issue, opened September 23, says 3.0 is "still used by 3.13" and that the 3.13 binaries are moving to 3.5 because of the EOL. On Linux, Python normally links the system library, so there you're back under your distro's patches.

And then there's all the stuff that vendors its own copy. Rust services built with the openssl crate's vendored feature. Conda environments. The monitoring agent your vendor ships as one fat binary. The appliance nobody has shelled into since the day it was racked. Each one carries its own OpenSSL and gets patched on its own schedule, or never.

Base images you forgot about

A container image freezes whatever library was current on the day it was built. A service nobody has rebuilt since spring runs spring's OpenSSL, no matter how carefully you patch the host under it. Alpine makes this painfully visible: Alpine 3.21 still ships OpenSSL 3.3.7, and upstream support for 3.3 ended on April 9, 2026. Alpine 3.22 is on 3.5.8. Pinning a base-image tag was supposed to buy you reproducibility. You got a frozen crypto library thrown in for free.

If image hygiene already keeps you up at night, our post on self-signed certificates breaking in Docker covers the trust-store flavour of the same frozen-layer problem.

Find every copy before Tuesday afternoon

Skip openssl version. It tells you which CLI is installed. It says nothing about the library a running process loaded.

Start with what's in memory. On each host, this lists every libssl and libcrypto that any process has mapped, vendored paths under /opt included:

sudo awk '/libssl|libcrypto/ {print $6}' /proc/[0-9]*/maps 2>/dev/null | sort -u

Then pull a version out of each file. OpenSSL embeds its version string in libcrypto, and statically linked binaries carry it too, so grep -a handles both:

for f in $(sudo awk '/libcrypto/ {print $6}' /proc/[0-9]*/maps 2>/dev/null | sort -u); do
  printf '%s: ' "$f"
  grep -aoE 'OpenSSL [0-9]+\.[0-9]+\.[0-9]+[a-z]* +[0-9]+ [A-Z][a-z]{2} [0-9]{4}' "$f" | head -1
done

# Static binaries: point it at the executable itself
grep -aoE 'OpenSSL [0-9]+\.[0-9]+\.[0-9]+[a-z]* +[0-9]+ [A-Z][a-z]{2} [0-9]{4}' "$(command -v node)" | head -1

Ask the runtimes too. They report what they actually use:

node -p process.versions.openssl
python3 -c 'import ssl; print(ssl.OPENSSL_VERSION)'
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'

For distro packages, grab the full version with the suffix. Once the CVEs are public, the suffix is what you compare against your vendor's security tracker:

dpkg-query -W -f='${Package} ${Version}\n' 'libssl3*'   # Debian / Ubuntu
rpm -q openssl-libs                                     # RHEL / Fedora
apk info -v 2>/dev/null | grep -E '^libssl3|^libcrypto3' # Alpine

For images, scan the image itself. An SBOM tool finds vendored copies that no package manager ever registered:

syft registry.example.com/api:prod -q | grep -iE 'openssl|libssl|libcrypto'

Run it over every image tag that's actually deployed. The tags in your Dockerfiles are a different list, and usually a shorter one. We made the same argument about certificates in you probably don't know how many certificates you have. The library underneath them has the identical problem.

Your TLS scanner can't see this

Here's the uncomfortable bit, and yes, we sell certificate monitoring. An external check sees the certificate, the chain, the protocol version and the cipher suite. It can't see which OpenSSL build produced the handshake. A server on a patched 3.5.9 and one on an abandoned 3.0.22 present the same certificate and negotiate the same TLS 1.3 suite. From the outside you can't tell them apart.

Library currency is an inventory job. Monitoring tells you the certificate on the front door expires in twelve days. It won't tell you the lock dates from 2021. You want both, and anyone who says one covers the other is selling something.

Moving to 3.5 without breaking the handshake

Go to OpenSSL 3.5. It's the current LTS, with public support until April 8, 2030. OpenSSL 4.0 is newer but isn't LTS, and its support ends on May 14, 2027. Fine if you enjoy upgrading every year. Bad if the point is never ending up here again. And don't hop sideways to 3.4: it goes end of life on October 22, 2026.

The upgrade has a cost. Two changes in 3.5.0 deserve a test before rollout.

First, the default TLS key shares changed. 3.5 offers X25519MLKEM768 next to X25519 and prefers hybrid post-quantum groups. Good news for harvest-now-decrypt-later, which we covered in your key exchange went post-quantum, your certificates didn't. It also makes every ClientHello about 1.2 KB bigger. Old middleboxes and hand-rolled TLS parsers that assume the ClientHello fits in one packet can choke on that, and what you see is a handshake timeout with no useful error. If that pattern shows up right after the upgrade, start with debugging TLS handshake failures. To check what a server negotiates:

openssl s_client -connect api.example.com:443 -groups X25519MLKEM768 </dev/null 2>/dev/null \
  | grep -iE 'group|temp key|^New,'

If one legacy path breaks while you hunt down the box responsible, give only that service its own config file and point it there with OPENSSL_CONF=/etc/ssl/legacy-groups.cnf. The system default stays as it is:

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Groups = X25519:secp256r1:secp384r1

Second, and smaller: openssl req, cms and smime now default to aes-256-cbc for encrypted output, where they used des-ede3-cbc before. Got a script that writes an encrypted key and hands it to some old consumer? Test it.

If 3.0 still lives in a TLS 1.2-only corner of your estate, that corner is on borrowed time anyway. RFC 9851 froze TLS 1.2 development, and RFC 10015 retired RSA and DHE key exchange. Moving to 3.5 is a good excuse to clean up both.

What to do this week

Before Tuesday, run the inventory and sort every hit into three buckets. Distro-packaged copies get patched the moment your vendor publishes. Copies bundled in a runtime mean upgrading the runtime. Copies vendored into something you can't rebuild mean leaning on a vendor, or parking that thing behind a proxy that terminates TLS for it.

Tuesday afternoon, read the advisory. If the bug hits your configuration, the first two buckets are an ordinary patch day. The third bucket is where you learn what "end of life" costs.

After that, rebuild images on a schedule. An image that never gets rebuilt quietly collects every EOL date that passes while it runs, and you only find out when an advisory like this one shows up.

Frequently asked questions

Is Ubuntu 24.04 affected because it ships OpenSSL 3.0? Not by the upstream EOL directly. Ubuntu backports security fixes into its own 3.0.13 package, so a patched libssl3t64 arrives through normal updates. The upstream EOL hits software that bundles its own copy of OpenSSL, such as official Node.js binaries or a vendored library inside a third-party agent.

Can I get OpenSSL 3.0.23 without paying? Not from the OpenSSL project. The September 23 announcement says 3.0.23 is available to premium support customers only. Your Linux distribution may ship an equivalent fix inside its own 3.0 package, but that's the distro's backport. Upstream publishes no public 3.0.23.

Should I upgrade to OpenSSL 4.0 or 3.5? For production, 3.5. It's the long-term support release with public fixes until April 8, 2030, while 4.0 is supported only until May 14, 2027. Pick 4.0 only if you need something it adds and you're ready to move again within a year.

Will the upgrade to 3.5 break existing TLS connections? Usually not. The new default key share X25519MLKEM768 does make the ClientHello about 1.2 KB larger, and some older middleboxes and embedded TLS stacks fail on that. Test outbound connections to legacy partners and internal appliances, and if one breaks, restrict the groups for that one client and leave the system-wide default alone.

Does an SSL monitoring tool detect an outdated OpenSSL version? No. External monitoring sees the certificate, chain, protocol and cipher, and those look identical whether the server runs a patched or an abandoned OpenSSL. Track library versions through host and image inventory, and keep certificate monitoring running next to it.

Related posts

Never miss an expiring certificate again

CertGuard watches your SSL certificates and domains, and alerts you long before anything expires. Free for your first five domains.