Skip to content

/errors/nodejs/eaddrinuse-address-already-in-use

Error: listen EADDRINUSE: address already in use :::3000

verified onenvironmentlocal · linux 6.18.44-fc-v153 x64 · GNU bash 5.2.21 · v22.22.0updated
tool
Node.js
exit code
1
versions
Node.js 18, Node.js 20, Node.js 22
os
linux, macos, windows

Error: listen EADDRINUSE: address already in use :::3000 means Node.js asked the operating system to listen on a port that another socket already owns. Only one process can bind a given address and port at a time, so the second listen() call fails. The code is EADDRINUSE and the process exits with status 1 when the error is not handled.

Reproduce it

The block starts one server, then tries to bind the same port from a second one in the same script. Port 34567 is only an example.

bash
node -e "
const net = require('net');
const first = net.createServer().listen(34567, '127.0.0.1', () => {
  net.createServer().listen(34567, '127.0.0.1');
});
" 2>&1 | grep -E "EADDRINUSE|address already in use" | head -3

Output

Error: listen EADDRINUSE: address already in use 127.0.0.1:34567
  code: 'EADDRINUSE',

The message is thrown from the listen call as an error event. Without a handler, Node prints the stack and exits.

Find the process that holds the port

On Linux, ss shows the owner (run it as the same user, or with sudo for other users' processes):

bash
ss -ltnp 'sport = :3000'

On macOS use lsof -nP -iTCP:3000 -sTCP:LISTEN. On Windows use netstat -ano | findstr :3000 and match the PID in Task Manager. The last column of each command is the process id.

Fix 1: stop the old process

If the owner is a leftover copy of your own server, stop it with Ctrl+C in its terminal or kill PID. Dev tools with file watchers sometimes leave a child process behind after the parent is killed, so check the PID again after stopping.

Fix 2: use a different port

Read the port from the environment so you can change it without editing code.

js
const port = Number(process.env.PORT ?? 3000);
server.listen(port);

Run PORT=3001 node server.js. On Windows PowerShell use $env:PORT=3001; node server.js.

Fix 3: handle the error or let the OS choose

Handling the event gives a clear message instead of a stack trace. Port 0 asks the OS for any free port, which suits tests.

bash
node -e "
const net = require('net');
const server = net.createServer();
server.on('error', (e) => console.log('listen failed:', e.code));
server.listen(0, '127.0.0.1', () => {
  console.log('listening on a free port:', server.address().port > 0);
  server.close();
});
"

Output

listening on a free port: true

Prevent it

Use one process manager per port, shut servers down on SIGINT and SIGTERM with server.close(), and keep fixed ports out of automated tests. In containers, remember that a published host port can also be taken by another container.

FAQ

Why does the address end in :::3000?

::: is the IPv6 wildcard address followed by the port, so the server was listening on all interfaces. With 127.0.0.1 you see 127.0.0.1:3000 instead.

Why does the port stay busy after I stop the server?

A process may still be running, or a sudden exit leaves connections in TIME_WAIT. Node sets SO_REUSEADDR on its listening sockets, so a restart on the same port normally works; a live process is the usual cause.

How do I find the process on Windows?

Run netstat -ano | findstr :3000 to get the PID, then tasklist /FI "PID eq PID" to see its name, and stop it with taskkill.

Sources