Skip to content

Node.js errorNode.js: “listen EADDRINUSE: address already in use”

The server will not start and prints Error: listen EADDRINUSE: address already in use, followed by the port (often :::3000 or :::5000). Another process already has that port open. Usually it is an older copy of the same server that never shut down, a second terminal running the dev server, or another app that uses the same default port.

Short answer

Find the process listening on the port and stop it. On macOS or Linux: lsof -nP -iTCP:3000 -sTCP:LISTEN, then kill the PID of the process that is listening. On Windows: netstat -ano | findstr LISTENING | findstr ":3000 ", then taskkill /PID <pid>. Or start your server on a free port (macOS/Linux: PORT=3001 node server.js). If it keeps coming back, a watcher such as nodemon is starting a second copy, or the old process is not closing on restart.

Why the port is taken, and the fix

  1. 01

    An old copy of your server is still running

    “An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.” Node.js, Errors: Common system errors

    A crashed terminal, a closed editor tab or a background job can leave the previous server running. Find the process that owns the port and stop it. Check what it is before you kill it, so you don’t stop a database or another app. Add /F to taskkill (or use kill -9) only if it refuses to stop. If docker ps shows a container publishing the port, stop the container instead.

    # macOS / Linux (listening process only)
    lsof -nP -iTCP:3000 -sTCP:LISTEN
    kill <PID>
    
    # Windows
    netstat -ano | findstr LISTENING | findstr ":3000 "
    taskkill /PID <PID>
  2. 02

    Another app uses the same default port

    Ports 3000, 5000 and 8080 are defaults for many tools. On macOS 12 (Monterey) and later, the AirPlay Receiver listens on ports 5000 and 7000; turn it off in System Settings, General, AirDrop & Handoff, or use another port. Read the port from an environment variable so you can move it without editing code.

    const port = Number(process.env.PORT) || 3000;
    app.listen(port, () => console.log(`Listening on ${port}`));
  3. 03

    Two servers start in the same process

    “This happens when another server is already listening on the requested port / path / handle.” Node.js, Net: server.listen()

    Calling listen twice, for example once in app.js and again in a test or a server.js that imports it, makes the second call fail. Export the app without listening, and call listen only in the entry file. In tests, use a test client that does not bind a port, or close the server after each run.

  4. 04

    Restarts do not wait for the old process

    With nodemon or a process manager, the new copy can start before the old one has released the port. Close the server on SIGINT and SIGTERM, and tell nodemon to use SIGTERM, because its default restart signal is SIGUSR2: nodemon --signal SIGTERM server.js. Avoid running two watchers on the same project.

    const server = app.listen(port);
    for (const sig of ['SIGINT', 'SIGTERM']) {
      process.on(sig, () => server.close(() => process.exit(0)));
    }

Checked against the vendor’s docs on : Node.js: Errors: Common system errors (EADDRINUSE); Node.js: Net: server.listen().

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: Node.js ENOENT: no such file or directory · Node.js “Cannot find module” · “Blocked by CORS policy” · “self-signed certificate in certificate chain”

Questions

More on this error

Is it safe to kill the process on the port?

Check its name first: lsof and Task Manager show it. If it is an old copy of your own node server, stopping it is safe. If it is a database, Docker or another app you need, start your server on a different port instead.

Why does it happen on the server after a deploy?

The new release starts while the old one is still running on the same port. Let the process manager stop the old process first, or use its reload command, and make the app close its server on SIGTERM.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.