Deploy Error Decoder

EACCES: permission denied — how to fix it

Quick answer: EACCES: permission denied means the OS blocked an operation you don't have rights for. The three common cases: binding a port below 1024 as non-root (listen EACCES 0.0.0.0:80), writing to a directory you don't own, or a broken npm cache. Don't reach for sudo or chmod 777 — run on a high port behind a proxy, or fix ownership properly.

Not your exact error? Paste it into the Deploy Error Decoder →
On this page

What the error looks like

The message names the operation it refused — port, path, or npm step:

Error: listen EACCES: permission denied 0.0.0.0:80

# or a file write:
Error: EACCES: permission denied, open '/var/app/out.log'

# or npm:
npm ERR! code EACCES   npm ERR! syscall mkdir

EACCES is always "you're not allowed," never "it doesn't exist." The fix is about privileges and ownership, not paths.

Why it happens

A privileged port (< 1024)

Binding 80/443 needs root or a capability; a normal user is refused.

Wrong file/dir ownership

The process user doesn't own the path it's writing to — common when a container runs as non-root.

Broken npm permissions

A global install or a cache owned by root blocks your user from writing.

Running as the wrong user

The service runs as a user that lacks rights to the resource it needs.

Diagnose it in three steps

1

Identify the operation

# Read the message: is it a port, a file path, or an npm syscall?
whoami; id        # which user is the process?
2

For a low port, don't run as root

# Run on a high port and reverse-proxy 80/443 to it:
PORT=3000 node server.js
# or grant just the bind capability (no full root):
sudo setcap 'cap_net_bind_service=+ep' $(which node)
3

For files/npm, fix ownership

sudo chown -R "$USER" /path/you/own      # not chmod 777
# npm: use a user-owned prefix instead of sudo installs
npm config set prefix ~/.npm-global
The real fix

Least privilege, not blanket permissions

The instinct to sudo or chmod 777 trades a quick fix for a security hole. The right shape: run the service as an unprivileged user on a high port, put a proxy in front for 80/443, and give the user ownership of exactly the paths it needs — nothing more.

How Infraveil handles this

Least-privilege by design

On your own servers, workload-service permissions are deployment- and component-specific and should be customer-reviewed. Separately, current Linux/systemd launcher deployments default to root, so review that launcher path for your deployment. Selected operational events may also be reported to hosted management. That is the same principle that fixes EACCES properly: grant exactly what is needed, not everything.

Review launcher and component permissions; Linux/systemd launcher deployments currently default to root
A built-in gateway fronts your services so apps can stay on high ports
Deploy approval uses the configured manual, exact-hash allowlist, or automatic mode; selected events are recorded on servers you control

Frequently asked questions

What does EACCES mean?

The operating system denied an operation because the process lacks the required permission — a privileged port, a file/directory it doesn't own, or a protected resource.

How do I fix 'listen EACCES permission denied :80'?

Ports below 1024 need privilege. Run your app on a high port (e.g. 3000) behind a reverse proxy, or grant just the bind capability with setcap cap_net_bind_service — don't run the whole app as root.

How do I fix npm EACCES errors?

Avoid sudo npm install. Set a user-owned global prefix (npm config set prefix ~/.npm-global) or use a version manager, then fix any root-owned cache ownership.

Should I use chmod 777 to fix EACCES?

No. 777 makes a path world-writable, which is a security risk. Fix ownership with chown so the correct user owns exactly the paths it needs.

Free tools for this

Client-side, no signup — they run in your browser.