Between October 2026 and December 2027, Python 3.10 and 3.11, .NET 8 and 9, PHP 8.2 and 8.3, Ruby 3.3, Node.js 22 and two Go releases lose upstream security fixes, and free Java 11 and 17 builds start running out. Inventory every runtime now, schedule upgrades by date, and gate new builds on supported versions.
"End of life" means something different for every language. Python gives each release five years. PHP gives four and ends on 31 December. Go supports only the two newest releases, so a Go version lives about a year. Java has no single end date: Oracle sells support in tiers and each OpenJDK distributor publishes its own calendar. This post puts every date on one page, taken only from each project's own pages, then compares support models, post end of life risk, and how to find old runtimes across an estate.
Key takeaways
- Ten upstream support endings fall inside the window, four of them in the last quarter of 2026 (Python 3.10, .NET 8, .NET 9, PHP 8.2). Node.js 22 on 30 April 2027 is the largest single deadline of 2027.
- Java needs a per distributor answer. Oracle Premier Support for JDK 17 ended in September 2026; free OpenJDK 17 builds run to September 2027, October 2027 or October 2029 depending on the builder.
- Support windows differ fivefold: about 12 months for Go, 24 for .NET STS, 36 for Node.js LTS, 49 for PHP and 60 for Python.
- Several lines are already past end of life and still running. Node.js 20, Python 3.9, PHP 8.1 and Ruby 3.2 get no upstream fixes, yet a major serverless platform lets existing functions on them run indefinitely.
- After end of life, vulnerabilities continue but advisories stop, so a clean scan of an old runtime proves very little.
- Trackers and cloud platforms disagree with upstream on several dates. We list five below. Plan against the project's own page.
The calendar: every runtime support ending from October 2026 to December 2027
This is the core table. Each row comes from the project's own release page, fetched on 23 October 2026. Where a project publishes only a month, or marks a date as expected, the table says so rather than inventing a day.
| Date | Runtime and version | What happens | Official source |
|---|---|---|---|
| September 2026 (month only) | Oracle JDK 17 | Oracle Premier Support ends; Extended Support continues to September 2029 | Oracle Java SE Support Roadmap |
| 1 October 2026 | Python 3.10 | End of life; no further security releases | devguide.python.org/versions |
| 20 October 2026 | Node.js 24 | Moves from Active LTS to Maintenance LTS (still supported) | nodejs/Release schedule.json |
| October 2026 CPU | Oracle JDK 21 | Updates from this Critical Patch Update onward are planned under the Java SE OTN license rather than a free use license (a license change, not an end of support) | Oracle Java SE Support Roadmap |
| 28 October 2026 | Node.js 26 | Enters Active LTS | nodejs/Release schedule.json |
| 10 November 2026 | .NET 8 (LTS) and .NET 9 (STS) | End of support, both on the same Patch Tuesday | Microsoft .NET support policy |
| 31 December 2026 | PHP 8.2 | Security support ends; branch reaches end of life | php.net/supported-versions |
| 31 December 2026 | PHP 8.4 | Active support ends; security fixes only until 31 December 2028 | php.net/supported-versions |
| Release of Go 1.28 (expected February 2027, no date published) | Go 1.26 | Minor releases, including security fixes, stop | go.dev release policy and release cycle |
| 31 March 2027 (marked "expected") | Ruby 3.3 | End of life | ruby-lang.org branches |
| 30 April 2027 | Node.js 22 | End of life | nodejs/Release schedule.json |
| Release of Go 1.29 (expected August 2027, no date published) | Go 1.27 | Minor releases, including security fixes, stop | go.dev release policy and release cycle |
| September 2027 (month only) | Microsoft Build of OpenJDK 11 and 17 | Earliest end of support date | Microsoft Learn OpenJDK support roadmap |
| October 2027 (month only, "scheduled") | Python 3.11 | End of life | devguide.python.org/versions |
| October 2027 ("at least") | Eclipse Temurin 11 and 17 | End of availability, stated as a minimum | adoptium.net/support |
| 31 December 2027 | PHP 8.3 | Security support ends; end of life | php.net/supported-versions |
| 31 December 2027 | PHP 8.5 | Active support ends; security only until 31 December 2029 | php.net/supported-versions |
Three things stand out. The last quarter of 2026 is crowded: Python 3.10, .NET 8, .NET 9 and PHP 8.2 all end within about three months. Node.js 22 is the big one for 2027, since it was the newest LTS line from October 2024 until Node.js 24 entered LTS in October 2025. And Go never appears as a calendar date: its support ends on an event, the next but one release.
Single version detail: Python 3.10 end of life, .NET 8 and .NET 9 end of support, and PHP 8.1 and the PHP 8.2 deadline.
How support models differ, runtime by runtime
Every project says "supported" and "end of life", but the phases underneath differ. Here they are side by side.
| Runtime | Release cadence | Phases | Typical total window | What "end of life" means | Who sets the date |
|---|---|---|---|---|---|
| Node.js | Two majors a year through v26; one a year from v27 | Current (6 months), then Active LTS, then Maintenance LTS | About 36 months from first release for LTS lines | No releases; security releases skip the line | Node.js Release Working Group |
| Python | One feature release a year, in October | Bugfix, then security only | 5 years | No security releases | Python core team, per release PEP |
| Java (Oracle JDK) | Feature release every 6 months; LTS every 2 years | Premier, Extended, Sustaining | Premier about 5 years for LTS; Extended about 8 | Each tier ends separately | Oracle |
| Java (OpenJDK builds) | Follows OpenJDK | Distributor specific | About 6 to 8 years observed for Java 17 | Quarterly updates stop | Each distributor |
| .NET | One major a year, in November | LTS (even) or STS (odd) | LTS 3 years, STS 2 years | No patches from Microsoft | Microsoft |
| PHP | One minor a year, around November or December | Active support (2 years), security only (2 years) | About 4 years, ending 31 December | No releases at all | PHP release managers |
| Go | Every 6 months, February and August | Supported until two newer majors exist | About 12 months | No minor or security releases | Go team |
| Ruby | One release a year, on 25 December | Normal maintenance, security maintenance, EOL | About 3 years and 3 months observed | No fixes from ruby-core | Ruby core team |
Node.js: LTS phases, and an annual cycle from v27
The Node.js previous releases page says a major spends six months as Current. Through Node.js 26, odd releases then went out of support and even ones moved to LTS. From Node.js 27 the cycle becomes annual and every major moves to LTS, after its Current phase and six more months of Alpha. The page says LTS "typically guarantees that critical bugs will be fixed for a total of 30 months", and that production should only use Active LTS or Maintenance LTS.
The nodejs/Release schedule.json file gives exact dates. Node.js 24 moved to maintenance on 20 October 2026 and ends on 30 April 2028. Node.js 26 enters LTS on 28 October 2026 and ends on 30 April 2029. Node.js 27 starts on 22 April 2027, enters LTS on 20 October 2027 and ends on 30 April 2030, with no maintenance date published yet.
Python: five years, with a longer bugfix phase from 3.13
The Python developer guide says support ends five years after release. Versions from 3.13 onward spend two years in the bugfix phase, where earlier versions spent 18 months, so the security only tail is shorter for new releases. Future end dates are published as a month only, such as "2027-10 (scheduled)" for Python 3.11, and past ones are not always 31 October: Python 3.10 ended on 1 October 2026 and Python 3.8 on 7 October 2024.
Java: Premier, Extended, and every distributor's own calendar
Oracle's Java SE Support Roadmap splits support into Premier, Extended and Sustaining tiers. JDK 17 Premier ended in September 2026, with Extended to September 2029. JDK 21 has Premier to September 2028 and Extended to September 2031; JDK 25 has Premier to September 2030 and Extended to September 2033. Oracle intends an LTS every two years, so the next is Java 29 in September 2027. Licensing overlaps: Oracle says JDK 21 updates from the October 2026 Critical Patch Update are planned under the Java SE OTN license. That is not an end of support, but it changes what a free, patched Oracle JDK means.
Other OpenJDK builders run their own calendars. Here is what each builder's page said on 23 October 2026.
| LTS version | Oracle Premier / Extended | Eclipse Temurin (end of availability) | Microsoft Build of OpenJDK (earliest end of support) | Amazon Corretto (end of life) |
|---|---|---|---|---|
| Java 8 | See Oracle page | At least December 2030 | Not built; Microsoft points to Temurin | December 2030 |
| Java 11 | See Oracle page | At least October 2027 | September 2027 | January 2032 |
| Java 17 | September 2026 / September 2029 | At least October 2027 | September 2027 | October 2029 |
| Java 21 | September 2028 / September 2031 | At least December 2029 | September 2028 | October 2030 |
| Java 25 | September 2030 / September 2033 | At least September 2031 | September 2030 | October 2032 |
So "is Java 17 end of life?" has four honest answers, depending on which build you ship; record the build vendor, not just the version. Adoptium promises LTS support "for at least four years", and Microsoft calls its dates "initial targets". For Java 11, see our Java 11 roadmap post.
.NET: LTS three years, STS two years, ending on Patch Tuesday
Microsoft's policy says LTS releases "get free support and patches for three years" and STS releases two years. End of support lands on the Patch Tuesday nearest the anniversary, which is why .NET 8 (released 14 November 2023) and .NET 9 (released 12 November 2024) both end on 10 November 2026. .NET 10, released 11 November 2025, runs to 14 November 2028. The page has no .NET 11 row yet.
PHP: two years active, two years security, ending 31 December
php.net says each branch is fully supported for two years, then supported "for two additional years for critical security issues only". Every current end date falls on 31 December. PHP 8.2 was first released on 8 December 2022 and its security support ends on 31 December 2026; PHP 8.1 ended on 31 December 2025 with 8.1.34. Security phase releases come "on an as-needed basis", so quiet months are normal.
Go: the two newest releases, and nothing else
go.dev says "each major Go release is supported until there are two newer major releases", and the release cycle page says Go ships every six months, in the second week of February or August. Go 1.24 shipped on 11 February 2025 and lost support when Go 1.26 shipped on 10 February 2026. Go 1.27 shipped on 19 August 2026. Because the end is an event, no day is published for Go 1.26's end; if the cycle holds it will be February 2027.
Ruby: four phases, one release every Christmas
ruby-lang.org lists branches as normal maintenance, security maintenance, EOL or preview, and says an EOL branch "does not receive any fixes". Releases land on 25 December. Ruby 3.2 reached EOL on 1 April 2026. Ruby 3.3 entered security maintenance on 1 April 2026 with EOL listed as 31 March 2027 "(expected)", and Ruby 3.4 and 4.0 show "TBD". The page calls its dates a "preliminary list".
Which versions are already end of life but still running?
These lines get no upstream fixes as of 23 October 2026. We found no primary dataset measuring runtime versions in production across many organisations, so we do not quote a share. What primary sources do show is that platforms still let them run.
| Runtime line | Upstream end of life | Official source | Serverless platform status (AWS Lambda docs) |
|---|---|---|---|
| Node.js 18 | 30 April 2025 | nodejs/Release | Deprecated 1 September 2025; updates blocked from 31 August 2027 |
| Node.js 20 | 30 April 2026 | nodejs/Release | Deprecated 30 April 2026; updates blocked from 31 August 2027 |
| Python 3.8 | 7 October 2024 | devguide.python.org | Deprecated 14 October 2024 |
| Python 3.9 | 31 October 2025 | devguide.python.org | Deprecated 15 December 2025 |
| Python 3.10 | 1 October 2026 | devguide.python.org | Deprecation date 31 October 2026 |
| PHP 8.0 | 26 November 2023 | php.net/eol | Not a managed runtime |
| PHP 8.1 | 31 December 2025 (last release 8.1.34) | php.net/eol | Not a managed runtime |
| Ruby 3.2 | 1 April 2026 | ruby-lang.org | Deprecated 31 March 2026 |
| .NET 6 | 12 November 2024 | Microsoft .NET policy | Deprecated 20 December 2024 |
| Go 1.25 | When Go 1.27 shipped, 19 August 2026 (1.25.14 shipped the same day) | go.dev | Go runs on OS only runtimes |
AWS says you "can continue to invoke your functions indefinitely" after deprecation, and it does not patch language runtimes past their end of support. A function created on Node.js 20 keeps answering requests on a runtime nobody patches. Most end of life exposure looks like this: no decision to keep old software, just no event that forces a change. See also Node.js 20 end of life.
How long is each runtime's support window?
Each figure is the gap from first release to the end date on the project's or distributor's own page, for a recent representative version. One bar block is about six months.
| Rank | Runtime line (example version) | Window | Bar (one block per ~6 months) | Free or paid |
|---|---|---|---|---|
| 1 | Amazon Corretto 17 | about 97 months (Sep 2021 to Oct 2029) | ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ | Free |
| 2 | Oracle JDK 17, Extended Support | 96 months (Sep 2021 to Sep 2029) | ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ | Paid |
| 3 | Eclipse Temurin 17 | at least 73 months (Sep 2021 to Oct 2027) | ▇▇▇▇▇▇▇▇▇▇▇▇ | Free |
| 4 | Microsoft Build of OpenJDK 17 | at least 72 months (Sep 2021 to Sep 2027) | ▇▇▇▇▇▇▇▇▇▇▇▇ | Free |
| 5 | Python 3.10 | 60 months (4 Oct 2021 to 1 Oct 2026) | ▇▇▇▇▇▇▇▇▇▇ | Free |
| 6 | Oracle JDK 17, Premier Support | 60 months (Sep 2021 to Sep 2026) | ▇▇▇▇▇▇▇▇▇▇ | Paid |
| 7 | PHP 8.2 | about 49 months (8 Dec 2022 to 31 Dec 2026) | ▇▇▇▇▇▇▇▇ | Free |
| 8 | Ruby 3.2 | about 39 months (25 Dec 2022 to 1 Apr 2026) | ▇▇▇▇▇▇▇ | Free |
| 9 | Node.js 22 LTS | about 36 months (24 Apr 2024 to 30 Apr 2027) | ▇▇▇▇▇▇ | Free |
| 10 | .NET 8 LTS | about 36 months (14 Nov 2023 to 10 Nov 2026) | ▇▇▇▇▇▇ | Free |
| 11 | .NET 9 STS | about 24 months (12 Nov 2024 to 10 Nov 2026) | ▇▇▇▇ | Free |
| 12 | Go 1.24 | about 12 months (11 Feb 2025 to 10 Feb 2026) | ▇▇ | Free |
| 13 | Node.js 25 (odd, Current only) | about 7.5 months (15 Oct 2025 to 1 Jun 2026) | ▇ | Free |
Windows are stable within each language because each rule is mechanical: Node.js LTS lines v20 to v26 all land between 35.8 and 36.4 months, and Ruby 3.1 to 3.3 all near 39 months. The variation between languages is large. Upgrading every four years keeps a Python team inside the window and leaves a Go team unsupported for three of those four years. Java's free builds look generous, but that length comes from distributors, and each one's end date is a separate promise to record.
What happens to vulnerabilities disclosed after end of life?
They still exist, but your tools stop hearing about them. A security fix normally means a patched release, an advisory naming the affected range, and scanners matching that range against your versions. After end of life the patched release stops by definition, and the advisory often lists only the supported lines that were patched.
Node.js tackled this directly. In its January 2025 security release it issued CVEs for end of life lines themselves: CVE-2025-23087 (Node.js 17 and earlier), CVE-2025-23088 (Node.js 19) and CVE-2025-23089 (Node.js 21). The same post says end of life versions "are always affected when a security release occurs". An unsupported line is presumed vulnerable to every later fix, not presumed clean.
Python, PHP, Ruby and Go define end of life as the end of fixes and promise no further advisory work; Ruby says an EOL branch "does not receive any fixes". So a scanner can report zero findings for an end of life runtime precisely because nobody tested or listed it.
Can we count CVEs that land in a runtime after end of life? Not honestly. If later advisories do not list the old range, any database query understates the number, and we would rather say so than publish a precise looking figure. Our post on why "no advisory" is not "safe" for end of life software covers how to treat these zero result scans.
Do Linux distributions or paid extended support change the effective date?
Sometimes, and you need to record which one applies.
Distributions. A runtime from your operating system's package manager is patched by the distribution while that release is supported. Ubuntu's release cycle page gives 22.04 LTS standard security maintenance to May 2027 and Expanded Security Maintenance to May 2032, and 24.04 LTS May 2029 and May 2034. Standard maintenance covers packages in Main; Universe packages get security coverage through Expanded Security Maintenance. Which one your runtime package sits in changes who patches it.
Distribution backports patch only the distribution's build. A runtime installed from a tarball, a version manager or a language project's container image is not covered, so two copies of "Python 3.10" on one host can have different support status.
Java distributors. Free OpenJDK builders publish dates often years beyond Oracle Premier Support, but only for their own build.
Cloud platforms. AWS says it "occasionally delays deprecation" of a Lambda runtime past the language's end of support, and in that period patches only the operating system. So the python3.10 deprecation date of 31 October 2026 is not a promise of Python patches; upstream Python 3.10 ended on 1 October.
Paid extended support. Commercial extended support is sold for some runtimes by third parties, which we do not name. If you buy it, record the contract end date as the effective date and add the seller's advisory feed to your matching, because upstream vulnerability data will not know about those patches.
The rule of thumb: the effective date is the one published by whoever builds the binary you run.
How do you find end of life runtimes in containers, SBOMs and serverless configs?
Runtimes hide in more places than application dependencies do.
| Where the runtime version lives | How to read it |
|---|---|
| Version files in repositories | .nvmrc, .node-version, .python-version, .ruby-version, .tool-versions, global.json, go.mod (the go and toolchain lines), runtime.txt |
| Package metadata | engines.node in package.json, requires-python in pyproject.toml, maven.compiler.release in pom.xml, TargetFramework in .csproj, require.php in composer.json |
| Container base images | FROM lines in Dockerfiles; environment variables in the built image |
| CI configuration | node-version, python-version, java-version, go-version inputs in workflow files |
| Serverless configs | Runtime identifiers such as nodejs20.x, python3.10, dotnet8 in function settings and infrastructure as code |
| SBOMs | Components named for the runtime, when the SBOM generator recorded them |
Step by step: build an end of life inventory
1. Find pinned runtime versions in your repositories.
git ls-files | grep -E '(^|/)(\.nvmrc|\.node-version|\.python-version|\.ruby-version|\.tool-versions|global\.json|go\.mod|runtime\.txt)$' \
| while read -r f; do echo "== $f"; head -5 "$f"; done
2. List every base image your Dockerfiles use, ranked by frequency.
grep -RhoE '^FROM[[:space:]]+[^[:space:]]+' --include='Dockerfile*' . \
| awk '{print $2}' | sort | uniq -c | sort -rn
Tags like node:20, python:3.10-slim, php:8.1-fpm and ruby:3.2 are end of life lines today. Tags like latest or lts tell you nothing until you inspect the built image.
3. Read the runtime version from built images. Official language images usually record the version in an environment variable. Check the image you actually deploy, not the Dockerfile.
docker image inspect --format '{{range .Config.Env}}{{println .}}{{end}}' myapp:prod \
| grep -E 'NODE_VERSION|PYTHON_VERSION|JAVA_VERSION|RUBY_VERSION|PHP_VERSION|GOLANG_VERSION|DOTNET_VERSION'
If the variable is missing, run the binary: docker run --rm --entrypoint python myapp:prod --version, or the same with node -v, java -version, php -v, ruby -v, go version or dotnet --list-runtimes.
4. Generate SBOMs for images and look for runtime components. With the Safeguard CLI you can scan an image or an existing SBOM file and get results as JSON under ./output:
safeguard scan --image myapp:prod
safeguard scan --sbom ./sbom.cdx.json
For a CycloneDX SBOM from any generator, this lists likely runtime components:
jq -r '.components[]
| select(.name | test("^(node|nodejs|python3?(\\.[0-9]+)?|openjdk.*|temurin.*|php[0-9.]*|ruby[0-9.]*|golang|go|dotnet.*|aspnetcore.*)$"))
| "\(.name) \(.version)"' sbom.cdx.json | sort -u
SBOM coverage of runtimes varies: a distribution package usually appears, a runtime copied in as a tarball may not. Our post on finding end of life components in your SBOM goes deeper on this gap.
5. List serverless functions by runtime. For AWS Lambda, per region:
for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
aws lambda list-functions --region "$r" \
--query "Functions[?Runtime=='nodejs20.x' || Runtime=='nodejs18.x' || Runtime=='python3.9' || Runtime=='python3.10' || Runtime=='ruby3.2' || Runtime=='dotnet6'].[FunctionName,Runtime]" \
--output text | sed "s/^/$r\t/"
done
Remember AWS's own warning: for functions deployed as container images, deprecation notifications are not sent. You have to read the image.
6. Check the runtime in CI. In GitHub Actions, pin a supported line explicitly rather than relying on a runner default.
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: actions/setup-python@v5
with:
python-version: "3.13"
7. Fail the build when a runtime passes its end date. For Node.js, the Release repository's schedule file is machine readable and is the project's own source:
MAJOR=$(node -p 'process.versions.node.split(".")[0]')
END=$(curl -fsSL https://raw.githubusercontent.com/nodejs/Release/main/schedule.json \
| jq -r --arg v "v$MAJOR" '.[$v].end')
TODAY=$(date -u +%F)
if [[ "$TODAY" > "$END" ]]; then
echo "Node.js $MAJOR reached end of life on $END"; exit 1
fi
For other runtimes, keep a checked in table of end dates copied from the official pages and review it each quarter.
Where Safeguard fits
Safeguard scans repositories, container images and SBOM files and shows which projects contain a given component and version, so "where do we still run Python 3.10?" becomes a search, not a survey. Policies generate findings and gates enforce them (block, warn, notify or require approval), so a rule like "no runtime component below a set version" can stop a new image before it ships. When a runtime move forces dependency upgrades, autonomous remediation can open those pull requests, ranked with reachability analysis. Safeguard does not patch an end of life runtime binary or change a cloud provider's managed runtime; the runtime upgrade is still your change.
How do compliance frameworks treat unsupported runtimes?
We checked CISA's guidance, the clearest primary source we could fetch. We did not verify clause text from PCI DSS, ISO 27001 or SOC 2 for this article, so we do not quote them; read your framework's own text before citing a clause to an auditor.
- Product Security Bad Practices, Version 2.0 (revised 17 January 2025). Software makers should "clearly communicate the period of support for their products at the time of sale" and patch throughout it, and should monitor open source dependencies for CVEs and alerts "such as end-of-life".
- BOD 26-02, Mitigating Risk From End-of-Support Edge Devices (issued 5 February 2026). It applies to federal civilian agencies and covers edge devices such as firewalls and routers, not runtimes. It requires an inventory within 3 months, removal of listed devices within 12 to 18 months, and continuous end of support tracking within 24 months. Not a runtime rule, but the same pattern: inventory, dated removal, continuous tracking.
- Open Source Software: Security Principles and Practices (CISA, published 30 July 2026). It suggests agencies that stop maintaining a project submit support information to endoflife.date and use the OpenEOX schema to share support status downstream, a sign that machine readable support data is becoming an expectation.
A defensible answer to "do you run unsupported software?" has three parts: an inventory that includes runtimes, a dated plan for each unsupported item, and evidence the plan is followed. This calendar is a start on the second.
What is a sensible upgrade cadence per runtime?
Cadence should follow the support model; one "upgrade yearly" rule fails for Go and wastes effort for Python.
| Runtime | Suggested cadence | Target line | Start the next upgrade when | Why |
|---|---|---|---|---|
| Node.js | Every LTS line, or every other one | Active LTS (Node.js 24 today; 26 from 28 October 2026) | A new line enters Active LTS | About 36 months per line |
| Python | Every one or two feature releases | A release in the bugfix phase (3.14 or 3.15 today) | A branch moves to security only | Libraries drop old Pythons before year five |
| Java | Every LTS (every two years) | The newest LTS your build vendor supports | The next LTS GA (Java 29, planned September 2027) | Vendor dates differ |
| .NET | Every LTS; adopt STS only if you upgrade yearly | .NET 10 today | Each November release | STS and LTS can end together |
| PHP | Every one or two minor releases | 8.4 or 8.5 | A branch leaves active support | Ends 31 December, inside freezes |
| Go | Every release, within six months | The newest Go release | Each February and August | Only two releases supported |
| Ruby | Every one or two releases | 3.4 or 4.0 | A branch enters security maintenance | About 39 months |
PHP and Ruby dates sit near year end and quarter end, when many teams freeze changes, so plan those upgrades a quarter early. If a framework sits on top with its own clock, read our post on framework and runtime end of life as two clocks.
Where sources disagree
We compared each official date against the secondary leads in our research notes and against one major cloud platform. These are the disagreements we found.
| Item | Official project page | Other source | Which to use |
|---|---|---|---|
| Python 3.10 end of life | 1 October 2026 (devguide.python.org) | 31 October 2026 in a third party tracker; Lambda deprecation also 31 October 2026 | 1 October 2026 for upstream fixes |
| Ruby 3.2 end of life | 1 April 2026 (ruby-lang.org) | 31 March 2026 in a third party tracker and as the Lambda deprecation date | 1 April 2026 upstream; the one day gap is immaterial, but cite the right page |
| Oracle JDK 21 license switch | October 2026 CPU; one regional copy of the Oracle page gives 20 October 2026 | Not applicable | Read Oracle's current page for your region |
| Node.js 20 first release | 18 April 2023 in schedule.json | 17 April 2023 on nodejs.org previous releases | Immaterial for planning; end date matches on both (30 April 2026) |
| Java 17 end | Oracle Premier September 2026 | Free builds September 2027 to October 2029 | The date published by the builder of your binary |
None moves a plan by more than a month, but an auditor will notice if your policy and your evidence cite different dates.
How we measured
- Sources. Every calendar and comparison date was read on 23 October 2026 from the project's or builder's own page (listed under Sources). Cloud dates come from AWS Lambda's documentation and distribution dates from Ubuntu's release cycle page.
- Oracle. Oracle's roadmap page returned an access error to our fetcher, so Oracle dates come from the roadmap's text as indexed on oracle.com, compared across regional copies. Verify them on the live page.
- Trackers. Third party trackers were leads only. Disagreements are recorded above, and the official date wins.
- Window lengths. Months from first release to published end date, rounded; a month only date counts as that month. Java distributor windows start at the OpenJDK GA month (September 2021 for Java 17).
- Go. End dates are events; we give the expected month from the published cycle and say no day is published.
- Not measured. Production prevalence of each end of life runtime, and CVE counts after end of life, for the reasons above.
Common mistakes
- Treating the base image tag as the runtime version.
node:ltsandpython:3move. Read the version from the built image you deploy. - Trusting a cloud platform's deprecation date as a patch date. AWS states it does not patch language runtimes after their end of support, even if the managed runtime deprecation comes later.
- Asking "is Java 17 end of life?" without naming the build. Oracle, Adoptium, Microsoft and Amazon give different answers. Record the vendor alongside the version.
- Reading a clean scan of an end of life runtime as safe. Advisories often stop listing old lines. Node.js says outright that end of life versions are always affected by later security releases.
- Assuming a distribution backport covers every copy. A distribution patches its own package, not a runtime installed by a version manager or copied into an image.
- Upgrading Go once a year. With two supported releases six months apart, a yearly habit leaves no margin: any slip and you are unsupported.
FAQ
Which runtimes reach end of life in 2026?
Ruby 3.2 (1 April), Node.js 20 (30 April), Python 3.10 (1 October), .NET 8 and .NET 9 (10 November) and PHP 8.2 (31 December). Go 1.24 and 1.25 lost support on 10 February and 19 August 2026. Oracle Premier Support for JDK 17 ended in September 2026.
Which runtimes reach end of life in 2027?
Go 1.26 (when Go 1.28 ships, expected February), Ruby 3.3 (31 March, expected), Node.js 22 (30 April), Go 1.27 (when Go 1.29 ships, expected August), Python 3.11 (October, day not published) and PHP 8.3 (31 December). Microsoft's and Adoptium's Java 11 and 17 builds reach their earliest stated ends in September and October 2027.
Is Python 3.10 end of life?
Yes, since 1 October 2026 according to devguide.python.org. Some trackers say 31 October; the official page says 1 October.
Is Node.js 22 still supported?
Yes. Node.js 22 entered Maintenance LTS on 21 October 2025 and is supported until 30 April 2027, per the Node.js Release schedule.
When does Java 17 support end?
It depends on the build: Oracle Premier ended September 2026 (Extended to September 2029), Microsoft's earliest end is September 2027, Temurin at least October 2027, Corretto October 2029.
How long is a Go version supported?
Until two newer major releases exist. With releases every six months, that is about 12 months. Go 1.24 shipped on 11 February 2025 and lost support when Go 1.26 shipped on 10 February 2026.
What happens if I keep running an end of life runtime?
No more fixes, and new vulnerabilities may never be listed against your version, so scanners can report nothing. Managed cloud functions keep running, unpatched, until updates are eventually blocked.
Does Ubuntu or another distribution keep my runtime patched after upstream end of life?
Only the distribution's own package, while that release is supported. Ubuntu covers Main packages under standard maintenance and Universe packages through Expanded Security Maintenance. Runtimes installed outside the package manager are not covered.
Fix it without waiting for upstream
A runtime upgrade drags dependencies with it, and once a line is past end of life no upstream fix is coming, which is the second gap described below.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
To try the CLI on your own repositories and images, download Safeguard and follow the CLI docs.
See how Safeguard would help
The first demo is a real Safeguard CLI session: asked to fix a lodash CVE, the assistant reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, and runs npm install and npm test with your approval. A Node.js 20 or 22 runtime upgrade follows the same pattern: change the pin, update the dependencies that need it, run the tests, approve each step.
Click through it at your own pace, or open it full screen.
The second demo sets up the Safeguard runner on your own machine, approves it with its device code, and scans from the terminal. That is how you run the image and SBOM scans from the inventory steps on images that stay on your network.
Click through it at your own pace, or open it full screen.
Quick check
Your service runs on the AWS Lambda python3.10 runtime, and the deprecation date is 31 October 2026. Are you getting Python security fixes until then?
No. Upstream Python 3.10 reached end of life on 1 October 2026, and AWS documents that it does not patch language runtimes after their end of support, even when the managed runtime deprecation comes later. Only the operating system layer is patched in that gap.
Your team upgrades Go once a year, every February. Is that enough to stay supported?
Only just. If each February you move to the release that just shipped, it stays supported until the next February release ships, so any delay in your upgrade leaves you unsupported. Upgrading after each release, twice a year, leaves a six month margin.
Sources
- Node.js Release Working Group: schedule.json
- Node.js: Previous releases and release phases
- Node.js: January 2025 security releases, including CVEs for end of life versions
- Python Developer's Guide: Status of Python versions
- Oracle Java SE Support Roadmap
- Eclipse Adoptium: Temurin support
- Microsoft Learn: Support roadmap for the Microsoft Build of OpenJDK
- Amazon Corretto FAQs
- Microsoft: .NET and .NET Core support policy
- PHP: Supported versions
- PHP: Unsupported branches
- Go: Release history and support policy
- Go wiki: Go release cycle
- Ruby: Ruby maintenance branches
- AWS Lambda: Runtimes and deprecation policy
- Ubuntu: Release cycle
- CISA: Product Security Bad Practices
- CISA: BOD 26-02, Mitigating Risk From End-of-Support Edge Devices
- CISA: Open Source Software Security Principles and Practices (July 2026)
- endoflife.date (community aggregator, for convenience only)
Last reviewed: 23 October 2026. Support dates change; check the linked project pages before planning around any date.