Skip to content
Latchkey

Node "listen EACCES permission denied" on a Privileged Port in CI - Fix It

listen EACCES means the process tried to bind a port it is not allowed to use. Ports below 1024 are privileged and a non-root CI user cannot bind them.

What this error means

A server start in CI throws Error: listen EACCES: permission denied 0.0.0.0:80 (or another low port) because the unprivileged runner user may not bind privileged ports.

node
Error: listen EACCES: permission denied 0.0.0.0:80
    at Server.setupListenHandle [as _listen2] (node:net:1792:21)
    at listenInCluster (node:net:1865:12) {
  code: 'EACCES', port: 80
}

Common causes

Binding a port below 1024 as a non-root user

Privileged ports require elevated capability; the CI runner user lacks it, so the bind is denied.

A hardcoded production port in tests

Test config reuses the production port (80 or 443) instead of an unprivileged test port.

How to fix it

Use an unprivileged port

  1. Bind to a port above 1024 (or 0 for ephemeral) in the CI environment.
  2. Drive the port from an env var so production keeps its low port.
JavaScript
const port = Number(process.env.PORT) || 3000;
server.listen(port);

How to prevent it

  • Read the listen port from configuration, default tests to an unprivileged or ephemeral port, and never hardcode privileged ports into code that runs as a non-root CI user.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →