vite lastVerified: 2026-06-14

Error: Cannot find module @rollup/rollup-linux-x64-gnu

Cannot find module @rollup/rollup-linux-x64-gnu — Vite/Rollup native binary

On this page
  1. What causes this error
  2. How to fix it manually
  3. Copy this prompt into your AI coding agent
  4. Why this prompt works
  5. Variants by symptom
  6. Related errors and tools

What causes this error

Rollup — the bundler Vite uses for production builds — ships its performance-critical core as platform-specific native binaries published under separate npm packages: @rollup/rollup-linux-x64-gnu for standard glibc Linux, @rollup/rollup-linux-x64-musl for Alpine and other musl-libc Linux, @rollup/rollup-darwin-arm64 for Apple Silicon, and so on. The right one for the current platform is pulled in as an optionalDependencies entry. When the matching package is absent at runtime, Rollup throws Cannot find module @rollup/rollup-<platform> the moment Vite starts a build.

The dominant trigger is a long-standing npm bug with optional dependencies and package-lock.json (npm/cli#4828). When npm install runs on one platform — a macOS or Windows developer laptop — the lockfile records only that platform’s optional binary. A later npm ci on a different platform (Linux CI, an Alpine Docker layer) reads the same lockfile and never installs the binary that the new platform actually needs. The build then fails even though the lockfile is “valid”.

The second trigger is node_modules portability. A Dockerfile that COPYs a host-built node_modules into a Linux image, or a CI cache restored across runner architectures, carries the wrong native binary. Native modules are not portable across libc implementations or CPU architectures, so a glibc binary copied into an Alpine (musl) image fails with the -musl variant of the message, and an x64 binary on an arm64 runner fails with the -arm64 variant.

How to fix it manually

Delete the desynchronized state and let npm resolve optional dependencies fresh for the current platform. Remove both node_modules and package-lock.json, then run npm install again — this is the canonical fix for the npm optional-dependency bug. In Docker, run the install inside the target image (RUN npm install) rather than copying a host node_modules in, and add node_modules to .dockerignore so a stray host copy never leaks into the build context. If you cannot reinstall, npm install @rollup/rollup-linux-x64-musl (match the variant to your platform) or npm rebuild rollup installs the missing binary directly. Switching to pnpm or yarn sidesteps the specific npm lockfile bug because their optional-dependency handling differs.

Copy this prompt into your AI coding agent

vite-rollup-optional-dependency-fix-prompt.md
# Goal
Fix this Vite/Rollup "Cannot find module @rollup/rollup-<platform>" error with the smallest
safe change. Identify whether it is the npm optional-dependency lockfile bug or a non-portable
node_modules copy before changing anything.

# Context

The full error message:

<paste the Cannot find module @rollup/rollup-... error and the platform suffix it names>

Where it fails: <local / Docker / CI provider>
The OS/libc where it fails: <glibc Linux / Alpine musl / macOS / Windows>
Package manager and lockfile: <npm / pnpm / yarn> + is package-lock.json committed?
Does the Dockerfile COPY node_modules from the host? <yes / no / not applicable>

# In-scope

- package-lock.json and node_modules reinstall steps
- Dockerfile install ordering and .dockerignore entries
- The single optionalDependencies / rollup binary at fault

# Out-of-scope

- Replacing Vite or Rollup with another bundler
- Upgrading unrelated dependencies
- Adding new build tooling or CI providers
- Pinning the native binary as a hard dependency for all platforms

# Verification

Run `rm -rf node_modules package-lock.json && npm install` then `npm run build` — confirm exit code 0.
In Docker, rebuild with `--no-cache` and confirm the build stage completes.
Confirm the platform suffix in the error matches the image (musl for Alpine, gnu for Debian/Ubuntu).

# Output format

1. One sentence: lockfile bug or non-portable node_modules copy.
2. The diff (only changed files: package.json scripts, Dockerfile, .dockerignore).
3. The verification output, last 10 lines.
4. One line: which platform binary the fixed install resolved.

Why this prompt works

Naming the platform suffix and the libc up front is the load-bearing instruction — it splits the two distinct failure modes immediately. A -musl suffix on an Alpine image points at a non-portable copy or a base-image mismatch; the same error on a Linux CI runner with a committed lockfile points at the npm optional-dependency bug. Asking whether the Dockerfile copies node_modules from the host catches the most common Docker variant without the agent guessing. The out-of-scope line that forbids pinning the binary as a hard dependency stops a tempting but wrong “fix” that breaks every other platform’s build.

Variants by symptom

SymptomLikely causeFirst command to try
Fails on Linux CI, works on dev laptopnpm optional-dependency bugrm -rf node_modules package-lock.json && npm install
-musl suffix on Alpine Docker imagenon-portable node_modulesRUN npm install inside image + .dockerignore
-arm64 / -x64 mismatchCPU architecture mismatchreinstall on the target architecture
Returns after a cache restorestale CI dependency cachekey the cache on lockfile hash + platform
Reappears intermittentlylockfile partially updatedswitch to pnpm/yarn or delete the lockfile

Frequently asked questions

Why does this happen in Docker or CI but not on my laptop?

npm records only the optional binary for the platform where you first ran install into package-lock.json. A later npm ci on Linux or Alpine reads that lockfile and never installs the binary the new platform needs.

Should I add @rollup/rollup-linux-x64-musl to my dependencies?

No. Pinning one platform binary as a hard dependency breaks installs on every other platform. Delete node_modules and package-lock.json and reinstall, or run the install inside the target image instead.

What is the difference between the -gnu and -musl errors?

The -gnu binary is for standard glibc Linux such as Debian and Ubuntu; the -musl binary is for Alpine and other musl-libc images. The suffix tells you which base image the build actually ran on.