Skip to main content
DevOps Insightsguides & answers

npm · troubleshooting

npm error code EACCES: permission denied, mkdir

npm tried to create a folder your account is not allowed to write to, usually the shared folder for global packages or a cache left owned by root. The fix is to install where you own the files, not to run npm with sudo.

Reproduced on npm 11.12.1, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 9 sections

Before you start

  • The path in the error message: it tells you which folder npm could not write.

Run this first

step 1 of 2
npm prefix -g

Look for A system folder (/usr, /usr/local) or one in your home

Shows where global packages go.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Which folder does the error's path point into?

Cause space

3 of 3 still possible

  • Global packages go to a folder owned by rootCommon
  • The npm cache contains files owned by rootCommon
  • A project folder or node_modules is owned by another userOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    npm prefix -g

    Shows where global packages go.

    Look for A system folder (/usr, /usr/local) or one in your home

  2. Step 2

    npm config get cache

    Shows the cache folder, the other place npm writes.

    Look for Compare its owner with your user if the error path is inside it

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

Global packages go to a folder owned by root

Common

Node.js from a system package or an installer puts the global prefix somewhere like /usr/local, which a normal account cannot write.

Confirm

npm prefix -g; ls -ld "$(npm prefix -g)/lib"

A prefix such as /usr/local whose lib folder is owned by root

Fix

  • Best, according to npm's documentation: install Node.js with a node version manager, which keeps Node, npm and global packages in your home folder.
  • Or move the global folder to one you own: npm config set prefix ~/.local, then add PATH=~/.local/bin:$PATH to ~/.profile and open a new shell.
  • For project tools, skip the global install: npm install --save-dev the tool and run it with npx.

The npm cache contains files owned by root

Common

An earlier sudo npm left files in ~/.npm that your account cannot change. npm detects this and prints the command to fix it.

Confirm

find ~/.npm -maxdepth 2 ! -user "$USER" | head

Any path printed: files in your cache not owned by you

Fix

  • Run the chown command npm prints, which gives the cache folder back to your user, for example sudo chown -R "$(id -u):$(id -g)" ~/.npm.
  • Then stop using sudo with npm, or it will happen again.

A project folder or node_modules is owned by another user

Occasional

A container, a CI step or an earlier sudo created node_modules as root, so a later npm install as your user cannot write into it.

Confirm

ls -ld . node_modules

An owner other than your user

Fix

  • Give the folders back to your user (sudo chown -R "$(id -u):$(id -g)" node_modules), or delete node_modules and install again as yourself.
  • In containers, run npm install as the same user that runs the app, or set the user before installing.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

npm install -g puts packages in one shared folder. On many systems that folder belongs to the administrator, so a normal user cannot write there and npm stops with EACCES. Running it once with sudo seems to work, but leaves root-owned files behind that break later installs. The lasting fix is a location your own account owns.

Words used on this page

Global install
npm install -g: installs a package for every project, usually to provide a command such as a CLI tool.
Prefix
The folder npm installs global packages under; npm prefix -g prints it.
Node version manager
A tool that installs Node.js and npm inside your home folder, so global installs never need administrator rights.
What is actually happening

Reproduced on 22 October 2026 by installing a small local package globally, without downloading anything. npm 11.12.1 on macOS, pointed at a folder it could not write, printed "npm error code EACCES", "npm error syscall mkdir" and "Error: EACCES: permission denied, mkdir" with the path, and exited 243. It then suggests trying "again as root/Administrator"; npm's own documentation recommends fixing where packages go instead.

On Ubuntu 24.04, Ubuntu's npm 9.2.0 installs global packages under /usr/local, which belongs to root, so a normal user gets "npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules'" on the first global install.

When the cache folder holds files owned by root, usually after an earlier sudo npm, npm says so directly: "Your cache folder contains root-owned files", followed by the exact sudo chown command for your user and cache folder.

How to tell this is your problem
WhereWhat you see
npm 10 and laternpm error code EACCES … npm error syscall mkdir … Error: EACCES: permission denied, mkdir '…'
npm 9 and earliernpm ERR! code EACCES … npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules'
Root-owned cacheYour cache folder contains root-owned files, due to a bug in previous versions of npm

How to know it is actually fixed

  • npm install -g works without sudo, and the command it installs is found on your PATH.

Stopping it happening again

  • Never run npm with sudo. Use a node version manager or a prefix in your home folder.
  • Prefer project-local tools run with npx over global installs.

Security considerations

  • Avoid sudo npm install -g: it runs the package's install scripts as root, and leaves root-owned files that cause the next EACCES.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it