npm "EROFS: read-only file system" - Fix Writes to a Read-Only Path in CI
EROFS means npm attempted to write to a path mounted read-only - a cache dir, node_modules, or a global prefix on a read-only layer. The fix is to redirect npm’s writes to a writable location.
What this error means
npm fails with EROFS: read-only file system for a path under the cache, prefix, or install dir. It is common in hardened containers, distroless/read-only root filesystems, or when installing into a read-only mounted volume.
npm error code EROFS
npm error syscall mkdir
npm error path /nonexistent/.npm
npm error errno -30
npm error Error: EROFS: read-only file system, mkdir '/usr/lib/node_modules/...'Diagnose it: what is different about the runner?
A build that passes locally and fails on a runner differs in a small number of predictable ways. Check those before changing build configuration, because the build config is usually not the thing that changed.
- run: |
node --version && npm --version
echo "NODE_ENV=$NODE_ENV CI=$CI"
nproc && free -h && df -h /
ls -la node_modules/.bin | headCommon causes
The npm cache or HOME points at a read-only path
A container with a read-only root filesystem leaves $HOME/~/.npm unwritable, so npm cannot create its cache directory.
Installing into a read-only mount
A global prefix or a project dir on a read-only volume cannot be written, so install or link operations hit EROFS.
How to fix it
Redirect npm writes to a writable dir
Set the cache and prefix to a writable, ephemeral location.
export npm_config_cache=/tmp/.npm
export npm_config_prefix=/tmp/.npm-global
npm ciMount a writable working area
- Give the container a writable
/tmpor a mounted volume for the workspace and cache. - Ensure
$HOMEis writable, or overridenpm_config_cache. - Install on a writable layer, not a read-only mount.
The three that account for most of them
- Case sensitivity. Linux runners are case sensitive, macOS is not. An import with the wrong case resolves locally and fails in CI.
- Out of memory. Exit code 137 is a SIGKILL from the kernel, not a build error. Raise
--max-old-space-sizeor use a larger runner. - devDependencies pruned.
NODE_ENV=productionmakesnpm ciskip devDependencies, so the build tool itself goes missing. Set it after install, not before.
How to prevent it
- Point npm cache/prefix at a writable path on read-only filesystems.
- Install on writable layers, not read-only mounts.
- Provide a writable HOME/tmp in hardened containers.