Skip to content
Skip to main content
Vercel and Node.js logo tiles between a stack of old green circuit boards and one new black board on a concrete bench, illustrating the Vercel Node.js 20.x discontinued error and the move to Node 24
8 min readBy Carlos Aragon

Vercel Node.js 20.x Discontinued Error: How to Fix It

The Vercel error "Node.js Version 20.x is discontinued and must be upgraded" means your new deployment resolved to Node 20, and since October 1, 2026 Vercel won't build it. Set "engines": { "node": "24.x" } in package.json and redeploy. That's the whole fix for most projects. The rest of this post is for when it isn't: when the dashboard already says 24 and the build still dies, when a semver range you thought was safe turns out not to be, or when you want to know what else is quietly on borrowed time. I deployed a throwaway project ten times this morning to find out.

What Does the Node.js 20.x Discontinued Error Mean?

Node.js 20 hit end of life on April 30, 2026. Vercel gave it five more months and, per its Node.js 20 deprecation changelog, disabled it for Builds and Functions on October 1. Here's what a blocked build prints with Vercel CLI 64.5.0:

Error: Node.js Version "20.x" is discontinued and must be upgraded.
Please set "engines": { "node": "24.x" } in your `package.json` file to use Node.js 24.

The deployment record tells you more than the log. Through the REST API it comes back with readyState: ERROR, errorStep: buildStep and errorCode: BUILD_UTILS_NODE_VERSION_DISCONTINUED. The gap between buildingAt and ready was 715 milliseconds. Your code never runs, no install, no next build. Vercel checks the version, says no and stops.

Your live site is fine. Your next deploy isn't. Existing deployments keep serving, and in my tests a failed production build never moved the production alias. The old version stayed up every time. That sounds harmless, but it's the worst kind of breakage: you find out when you push the urgent hotfix, not on a calm Tuesday.

Which Settings Trigger It? I Tested 9 Setups

I created an empty project with one serverless function that returns process.version, then deployed it to production over and over, changing one thing at a time. Same team, same CLI, October 17, 2026.

What I setResultRuntime reported
"engines": { "node": "20.x" }Failed at build step-
"engines": { "node": "^20.11.0" }Failed at build step-
"engines": { "node": ">=18 <21" }Failed at build step-
"engines": { "node": ">=20" }Builtv24.21.0
"engines": { "node": "22.x" }Builtv22.23.2
No engines, project set to 24.xBuiltv24.21.0
No engines, project set to 20.x via APIFailed at build step-
"engines": "24.x", project set to 20.xBuiltv24.21.0
.nvmrc = 20, .node-version = 20.19.0Builtv24.21.0

Four things in that table are worth slowing down for.

Ranges that include 20 aren't always fatal

Vercel resolves the range to a major it still offers. >=20 resolved to 24 and built. ^20.11.0 and >=18 <21 can only be satisfied by 20, so they failed. If your engines field has a ceiling, that ceiling is what breaks you.

Open ranges float to whatever is newest

>=20working feels like good news. It's really a time bomb pointed the other way. Today it means 24. The day Vercel adds Node 26, it means 26, on a deploy where you changed nothing. Pin the major.

engines beats Project Settings, both directions

With the project set to 20.x and engines set to 24.x, the build ran on Node 24. Flip it and a 20.x enginesfails even when the dashboard says 24. This is the "I already changed the setting and it still fails" case.

.nvmrc does nothing on Vercel

With .nvmrc set to 20 and .node-versionset to 20.19.0, the function reported v24.21.0. Vercel doesn't read either file. So a team running Node 20 locally through nvm has been testing on a different runtime than production for as long as the project has been on 22 or 24, without anyone deciding that.

Why Can the API Still Set Node 20?

The dashboard greys out 20.x. The REST API doesn't. A PATCH /v9/projects/:id with {"nodeVersion":"20.x"} came back 200 with nodeVersion: "20.x" saved on the project. The next deploy with no engines field failed with a slightly different message: "Please set Node.js Version to 24.x in your Project Settings."

That matters if you create projects from code. A provisioning script, a Terraform module or an internal template that hardcodes nodeVersion: "20.x"will keep creating projects that can't deploy, and nothing fails until the first build. I generate a lot of preview projects from scripts, so this was the first place I looked.

How Do I Fix It Without Breaking the App?

Budget 20 minutes per project. Most of that is the local test, not the config change.

1. Find where Node 20 comes from

Look at package.json first, since it wins. Only if there's no engines field does the Node.js Version under Settings → Build and Deployment matter. In a monorepo, check the package.jsonin the project's root directory, not just the repo root.

2. Pin Node 24

{
  "engines": {
    "node": "24.x"
  }
}

24.x, not >=20. Vercel's supported Node.js versions page lists only 24.x (default) and 22.x right now, and only majors are selectable. Patch updates roll out on their own.

3. Make local and CI match

Set .nvmrcto 24 anyway. Vercel ignores it, but your laptop and your teammates don't. Update node-version in any GitHub Actions setup-node step, bump Docker base images, then do a clean rm -rf node_modules && npm ci && npm run build on 24. Native modules and old @types/nodeversions are the usual suspects. It's the same inventory-first habit I used for the n8n 3 breaking changes.

4. Redeploy and check the runtime

Don't trust the setting, trust the process. Log process.version from any function or add node -v to the build command, deploy, and read it back.

5. Can't upgrade yet?

Vercel's escape hatch is a container: add a Dockerfile.vercelto the project root and you pick the Node version yourself. I haven't shipped one, and I wouldn't for this. You inherit patching an end-of-life runtime that no longer gets security fixes, which is the opposite of why you're on Vercel.

How Do I Find Every Affected Project?

Vercel's answer is vercel project ls --update-required. Use the latest CLI; the Homebrew build on my Mac mini was 14 major versions behind npm. It only checks one scope at a time, though, and I work across my own team plus several client teams. So I hit the API instead:

import json, os, urllib.request

TOKEN = os.environ["VERCEL_TOKEN"]

def get(url):
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {TOKEN}"})
    return json.load(urllib.request.urlopen(req))

for team in [t["id"] for t in get("https://api.vercel.com/v2/teams")["teams"]]:
    until = ""
    while True:
        page = get(f"https://api.vercel.com/v9/projects?limit=100&teamId={team}{until}")
        for p in page["projects"]:
            if p.get("nodeVersion") != "24.x":
                print(team, p["name"], p.get("nodeVersion"))
        nxt = page["pagination"].get("next")
        if not nxt:
            break
        until = f"&until={nxt}"

Result: 233 projects across six teams, zero on 20.x, 12 on 22.x. The zero was nice, and partly luck: a lot of those are recent preview projects that simply defaulted to 24. The 12 on 22.x include this blog, my agency site and a few older Next.js apps, all part of the stack I use to ship client AI agents.

One gap: the script reads Project Settings, and engines overrides them. A project can show 24.x in the API and still fail if its repo pins 20. So pair it with a grep across your repos: grep -rn '"node":' --include=package.json . | grep -v node_modules.

Should You Pin Node 22 or Node 24?

24. Skip 22 unless a dependency forces it. The Node.js release schedule puts Node 22's end of life at April 30, 2027 and Node 24's at April 30, 2028. If Vercel follows the same pattern it just used for 20, which was end of life plus five months, a 22.x pin is looking at another forced migration around fall 2027. That's my extrapolation, not a Vercel announcement. Moving to 22 today means doing this twice in a year.

So yes, this blog is on that list of 12, and it moves to 24 next. If you run durable agents on Vercel Workflow or functions that talk to a database like the one in my Supabase + n8n lead database build, test those paths on 24 locally before you flip production. They exercise more of the runtime than a static marketing site does.

How I checked this: ten production deployments of a throwaway project (one Node function returning process.version) with Vercel CLI 64.5.0 on October 17, 2026, plus one PATCH /v9/projects call and the /v13/deploymentsrecord for the failed builds. The project was deleted afterward. Version mappings beyond what I deployed come from Vercel's docs and changelog, and end-of-life dates from the Node.js release schedule, all read the same day. Project counts come from the Vercel API across the teams my token can see.

Vercel Node.js 20 FAQ

Why does Vercel say Node.js Version 20.x is discontinued?

Vercel stopped building new deployments on Node.js 20 on October 1, 2026, after Node 20 reached end of life on April 30, 2026. Any new build that resolves to Node 20, from package.json engines or from Project Settings, fails at the build step with errorCode BUILD_UTILS_NODE_VERSION_DISCONTINUED.

Will my existing Vercel deployments on Node 20 stop working?

No. Vercel says already-deployed functions keep running, and in my tests a failed production build never moved the production alias, so the last good deployment kept serving. The problem shows up the next time you deploy, including hotfixes.

I changed Project Settings to Node 24 but the build still fails. Why?

package.json engines.node overrides Project Settings. If engines says 20.x, ^20.11.0 or a range capped below 21, the build fails no matter what the dashboard says. Change engines to 24.x or remove it.

Does Vercel read .nvmrc?

No. A deployment with .nvmrc set to 20 and .node-version set to 20.19.0 built and ran on Node v24.21.0 in my test. Vercel only looks at package.json engines and the Project Settings Node.js Version.

Should I move to Node 22 or Node 24 on Vercel?

Node 24. Node 22 reaches end of life on April 30, 2027, so a 22.x pin buys you months, not years. Node 24 is supported until April 30, 2028 and is Vercel's default for new projects.

Stuck on a Deploy That Won't Build?

I build and run Next.js apps and AI agents on Vercel for my own agency and for clients. If an upgrade is blocking a release, send me the repo and the failing deployment and I'll get it building on Node 24.

Related Posts