On October 14 the Next.js team shipped the out-of-band security update it had announced the week before: three vulnerabilities fixed in 16.4.1 and 15.5.28. On October 21 Next.js 15 turned two, and its maintenance window closed. If you have a site or app still on 15, move it to at least 15.5.28 now, because it's very likely the last patch that line will get. To check which version you're on, run npm ls next in the project folder.
What the October 14 patch fixed
The flaw that reaches back furthest is CVE-2026-96889, rated Critical. A memory bug in the library Next.js uses for image optimization lets an unauthenticated attacker run code on the server when the app processes SVG files on glibc-based Linux. Every version from 10 through 15.5.27 is affected, and 16 up to 16.4.0. If you can't upgrade right away, the advisory gives a stopgap: make sure sharp is at 0.35.5 or later. That only covers this one flaw.
The second Critical one, GHSA-673q-mjm6-r5xr, only hits 16: remote code execution in use cache functions that return multiple typed arrays, in apps using the App Router with Cache Components. There's no workaround for it. The third, GHSA-p3m5-59mp-jv5r, is High: crafted requests can pin the CPU of an App Router app with at least one Server Action until the process stops answering. It affects 13 and later.
For 15 there is exactly one fixed version, 15.5.28. For 13 and 14, which are exposed to two of the three flaws, nothing shipped.
What "out of support" means
Under the Next.js support policy, a major version stays in Active LTS until the next one ships. It then moves to Maintenance LTS, where it gets only critical bug fixes and essential security updates, and stays there for two years from its own release. Next.js 15 shipped on October 21, 2024, so the two years ran out on October 21, 2026. On October 22 the table on that same page still listed 15 as Maintenance LTS, but the two-year rule is written a few lines above it.
Your site keeps running exactly as before. What it loses is fixes: the next flaw will be closed on 16 and left open on 15. The policy adds that "in rare circumstances", if the bug is severe enough, the team will patch versions outside the policy. That happened in December 2025, but nobody can tell you in advance whether it will happen for the next one. The same applies to PHP 8.2, which loses security support on December 31.
44 security advisories in 2026
The project's list of advisories shows 44 published between January 1 and October 21, 2026, five of them Critical. In August, a flaw in AVIF image optimization allowed unauthenticated remote code execution. It affected every version from 10 onwards and was fixed only in 15.5.24 and 16.3.3. October went the same way, with SVG.
Versions 13 and 14 were left exposed both times. Teams on 15 but on an older minor, say 15.2, first had to move up to 15.5, because in August and October that's the only place fixes landed. After October 21, the next flaw like these will put teams on 15.5 in the same position.
The precedent: React2Shell
On December 3, 2025, CVE-2025-55182 went public. Nicknamed React2Shell, it was unauthenticated remote code execution in React Server Components, scored 10 out of 10. According to Invicti, the first real attacks were seen the next day. On December 11 the related flaws came out, including a denial of service that the team also fixed on 14, out of support since October, with 14.2.34.
Teams on a current version got away with changing one number in package.json and redeploying; teams one or two majors behind had to catch up first, in a hurry, with attacks already underway.
What changes when you move to Next.js 16
You start with the official codemod, npx @next/codemod@canary upgrade latest, which handles the mechanical parts: it renames middleware to proxy and swaps next lint for ESLint, for example. The upgrade guide is upfront that it doesn't do everything. If your code still reads cookies(), headers(), params or searchParams synchronously, which 15 tolerated with a warning, you need a second command, npx @next/codemod@canary next-async-request-api ., because 16 drops synchronous access entirely.
Changes that break the build
Node.js 20.9 is the new minimum and Node 18 is no longer supported, so on some hosts and pipelines that's the first thing to upgrade. Turbopack becomes the default for next build too, and if the project has a webpack config, maybe one a plugin added, the build stops; next build --webpack keeps webpack. Parallel routes need an explicit default.js for every slot or the build fails. And calling revalidateTag with a single argument is now a TypeScript error: it wants a second one, a cacheLife profile.
Changes that alter behaviour without errors
These do more damage, because the build passes and the problem shows up in production. proxy runs on the Node.js runtime only, so middleware that relied on edge should stay as it is rather than be renamed. next/image caches images for 4 hours instead of 60 seconds, and by default allows a single quality, 75: a direct request to /_next/image with any other value gets a 400. Images from local IP addresses are blocked, an SSRF protection that breaks setups on a private network until you turn on dangerouslyAllowLocalIP. And serverRuntimeConfig and publicRuntimeConfig are gone, replaced by environment variables.
None of these means rewriting the app, but you want to find them all on a test copy, not one at a time after release.
How we approach it
When we're the ones doing the 15 to 16 upgrade, this is the order:
- A starting snapshot: Next.js, React and Node versions, dependencies that only declare compatibility with 15, webpack configs added by plugins.
- A separate branch, both codemods, then a manual review of the changes, file by file.
- Testing on a preview identical to production, with extra attention to images, caching, authentication and redirects.
- Release only once the preview behaves like the current site, with the way back already prepared.
If you don't know which version your app runs on, or you know it's behind, get in touch or see how we handle upgrades of existing software. We start from a snapshot of where things stand and tell you how much work there is, before touching the code.

