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
- Bind to a port above 1024 (or 0 for ephemeral) in the CI environment.
- 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
Node EADDRINUSE "address already in use" for a Test Server in CI - Fix Port ConflictsFix the Node.js EADDRINUSE "address already in use" error for a test server in CI by closing the previous lis…
Node ERR_SOCKET_BAD_PORT in CI - Pass a Valid Port NumberFix the Node.js ERR_SOCKET_BAD_PORT error in CI by passing an integer port in range instead of undefined, a s…
Node "Error: write EPIPE" in CI - Handle the Broken PipeFix the Node.js "Error: write EPIPE" in CI by handling the stream error when a downstream reader closes the p…