Skip to content
Latchkey

NestJS "EADDRINUSE: address already in use" in e2e in CI

Two Nest e2e suites tried to bind the same fixed port, or a prior app was never closed. In CI the second listen fails with EADDRINUSE because the port is still held.

What this error means

An e2e run fails with "Error: listen EADDRINUSE: address already in use :::3000" when a suite calls app.listen on a hardcoded port that another test already bound.

NestJS
Error: listen EADDRINUSE: address already in use :::3000
    at Server.setupListenHandle [as _listen2] (node:net:1872:16)

Common causes

A previous app was not closed

A suite called app.listen(3000) but never app.close(), so the port stays held when the next suite starts.

e2e tests bind a real fixed port unnecessarily

Using app.listen(3000) in tests, instead of the in-memory server, causes collisions when jest runs suites in parallel.

How to fix it

Use the in-memory server, not a real port

  1. Prefer app.init() and app.getHttpServer() over app.listen() in tests.
  2. This avoids binding a real port entirely, so collisions cannot happen.
  3. Close the app in afterAll to release any resources.
app.e2e-spec.ts
await app.init();
return request(app.getHttpServer()).get('/health').expect(200);

Close the app or use port 0

If you must listen, close in afterAll or bind port 0 so the OS assigns a free port.

app.e2e-spec.ts
afterAll(async () => { await app.close(); });

How to prevent it

  • Use app.getHttpServer() in e2e tests instead of a real port.
  • Always close the app in afterAll.
  • If listening is required, bind port 0 to avoid fixed-port collisions.

Related guides

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