Node EADDRINUSE "address already in use" for a Test Server in CI - Fix Port Conflicts
EADDRINUSE means a server tried to bind a port that another process already holds. In CI it usually means a previous test server was never closed.
What this error means
A test or integration step throws Error: listen EADDRINUSE: address already in use :::3000. A second listener cannot bind because a prior one is still open.
Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenHandle [as _listen2] (node:net:1817:16)
at listenInCluster (node:net:1865:12) {
code: 'EADDRINUSE', port: 3000
}Common causes
A previous test server was not closed
A test suite started a listener and a later suite tries to bind the same fixed port without the first being torn down.
Parallel test workers sharing a hardcoded port
Concurrent workers each bind the same fixed port, so all but the first fail.
How to fix it
Bind to an ephemeral port
- Listen on port 0 so the OS assigns a free port.
- Read the assigned port back from the server address for client connections.
const server = app.listen(0);
const { port } = server.address();Always close servers in teardown
- Close the listener in an afterAll/afterEach hook.
- Await the close so the next suite can bind cleanly.
afterAll(() => new Promise((r) => server.close(r)));How to prevent it
- Use ephemeral ports for test servers, close every listener in teardown, and avoid hardcoded ports shared across parallel workers.