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.

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

Infraveil's agent runs your services on your own servers with least-privilege access — it doesn't need blanket root to operate, and every action it takes is approval-gated and recorded. That's the same principle that fixes EACCES properly: grant exactly what's needed, not everything.

The agent operates with least-privilege access, not blanket root
A built-in gateway fronts your services so apps can stay on high ports
Every action approval-gated and 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.