All guides (in French)Lire en français
Deploy5 min read

The “Cannot find native binding” error

The message points you to an npm bug and tells you to delete your lockfile. That advice fixes one case out of two. In the other, the most common today, you can delete and reinstall as often as you like: the error comes back word for word, because it comes from your Node version. Two commands are enough to know which case you are in.

What this guide proves

  • Both causes reproduced separately, with the exact output of each.
  • Proof that the message’s advice does not fix the first one.
  • Two commands to find out which one affects you.

The message

$ npm ci && npx vite build, on Node 22.11.0
Error: Cannot find native binding. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
    at file:///app/node_modules/rolldown/dist/shared/binding-BbrDfv1x.mjs:602:34
    at file:///app/node_modules/rolldown/dist/shared/binding-BbrDfv1x.mjs:9:49
Actual output, in a node:22.11.0 container (linux/amd64), on 23 September 2026.

rolldown, the bundler behind Vite 8, is written in Rust. It ships as one binary per system: one for macOS on Apple silicon, one for Linux x64, and so on. npm only installs the one for the current machine, treating it as an optional dependency. The message simply says this binary is missing from node_modules. It does not say why, and there are two possible reasons.

Find out which one affects you

terminal
node -v
grep -c '"node_modules/@rolldown/binding-linux-x64-gnu"' package-lock.json
Run it where the build fails: your CI, your host’s container, or your machine.
What you getThe causeThe fix
Node below 22.12 (or below 20.19 on 20.x)Node is too old: npm silently skips the binary.Upgrade to Node 22.12 or later.
Recent enough Node, and 0 from grepThe lockfile does not know the Linux binary.Regenerate the lockfile, or do not ship it.

Cause 1: Node is too old

Rolldown’s Linux binary declares the Node versions it accepts: ^20.19.0 || >=22.12.0. On Node 22.11, npm sees that it does not fit and, since it is an optional dependency, skips it. No error, not even a warning in its name. You need npm’s most verbose mode to see it.

$ npm ci --loglevel=silly | grep binding-linux-x64-gnu, then ls node_modules/@rolldown
npm verbose reify failed optional dependency /app/node_modules/@rolldown/binding-linux-x64-gnu

pluginutils
Actual output, on Node 22.11.0, on 23 September 2026.

The @rolldown folder only holds pluginutils: no binary. On Node 22.12, with the same project and the same lockfile, it holds binding-linux-x64-gnu and the build succeeds. The only visible clue during the install is an EBADENGINE warning for rolldown and vite, which scrolls past long before the error.

This is where the message’s advice misleads. We followed it to the letter on Node 22.11: delete the lockfile and node_modules, then npm i.

$ rm -rf node_modules package-lock.json && npm i && npm run build (EBADENGINE lines and error)
npm warn EBADENGINE   package: '@vitejs/plugin-react@6.1.1',
npm warn EBADENGINE   package: 'vite@8.3.0',
npm warn EBADENGINE   package: 'oxlint@1.85.0',
npm warn EBADENGINE   package: 'rolldown@1.2.9',

Error: Cannot find native binding. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
Actual output, on Node 22.11.0, with the Vite 8 + React template from create-vite, on 23 September 2026.

Same error, word for word. The fix is elsewhere: declare a sufficient version in the project. The versions tested one by one, and how to set it at each host, are in our guide to the “styleText” error, which hits even older versions.

package.json
{
  "engines": {
    "node": ">=22.12"
  }
}
At least 22.12: just “22” can still give you 22.11 depending on the environment.

Cause 2: the lockfile does not know the Linux binary

This is the npm bug the message quotes, open since 2022. Under some conditions, a package-lock.json made on a Mac only records the macOS binary. npm ci, which installs exactly what the lockfile says, then has nothing to install for Linux.

We reproduced that state by removing the non-macOS binary entries from the lockfile, then building on Node 22.14, a sufficient version. Only the binary is missing: the message is the same.

$ npm ci && npx vite build, lockfile without the Linux entries, on Node 22.14.0
Error: Cannot find native binding. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
Actual output, in a node:22.14.0 container (linux/amd64), on 23 September 2026.

Here, the message’s advice is right. Regenerate the lockfile with a recent npm, which records the binaries for every platform. The one we made on a Mac with npm 11 listed fifteen of them, Linux included, and built without errors on Linux.

terminal
rm -rf node_modules package-lock.json
npm i
grep -c '"node_modules/@rolldown/binding-linux-x64-gnu"' package-lock.json
On your machine, then commit the new lockfile.

If you cannot regenerate the lockfile, do not ship one at all: the server will resolve the dependencies itself, on Linux.

Sources

  1. [1]npm/cli, issue 4828, the bug of optional dependencies missing from the lockfile, quoted by rolldown’s message.
  2. [2]The @rolldown/binding-linux-x64-gnu package, engines field: ^20.19.0 || >=22.12.0, read from the rolldown 1.2.9 lockfile.
  3. [3]Our tests, official Docker images node:22.11.0, 22.12.0 and 22.14.0 on linux/amd64, Vite 8.3.0 project, on 23 September 2026.

Your project online. Hosted in Switzerland.

A repository, an archive or a site already online. We detect it, build it and put it online over HTTPS. 30 days free.