EADDRINUSE

Node.js EADDRINUSE: address already in use when restarting server

Programming & Dev Tools Beginner 👁 4 views 📅 May 29, 2026

Your Node server's port is still held by a previous process. Kill it or pick another port.

What causes EADDRINUSE and the quick fix

You stop your Node server with Ctrl+C, but when you start it again seconds later, you get EADDRINUSE: address already in use :::3000. The OS is still holding the port. Your process didn't fully release it yet. The socket enters a TIME_WAIT state, which on Linux can last 60 seconds. Windows and Mac behave similarly.

The absolute fastest fix: pick a different port number. If your app usually runs on 3000, try 3001 or 8080. That gets you back to work in 10 seconds.

But you probably want to keep the same port. Here's how to actually free it up.

Cause #1: The old Node process is still running

Most common scenario: you closed the terminal or hit Ctrl+Z instead of Ctrl+C. The process keeps running in the background. When you restart, the port is taken by that orphaned process.

How to find and kill it

On Linux or Mac, open a new terminal and run:

lsof -i :3000

You'll see output like:

COMMAND   PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node     12345  you    11u  IPv4 0x1234567890abcdef      0t0  TCP *:3000 (LISTEN)

The PID (process ID) is the number you need. In this example it's 12345. Kill it:

kill -9 12345

After you run that, try starting your Node server again. It should bind to port 3000 without error.

On Windows, use:

netstat -ano | findstr :3000

You'll see something like:

TCP    0.0.0.0:3000   0.0.0.0:0   LISTENING   12345

The last number (12345) is the PID. Kill it:

taskkill /F /PID 12345

Then restart your server.

Why this happens

When you close a terminal tab that was running a Node process, the process may not be terminated — it just loses its parent. On Unix systems, it gets reparented to init (PID 1) and keeps running. The port stays open.

I've seen this happen constantly with developers using VS Code's integrated terminal: they close the terminal panel thinking that stops the process. It doesn't. You have to explicitly send a SIGTERM or kill the process.

Cause #2: TIME_WAIT state after a graceful shutdown

You properly stop your server with Ctrl+C, but restart immediately and get EADDRINUSE. This is the TIME_WAIT state. On Linux, the socket lingers for 60 seconds by default. On Windows, it's typically 240 seconds. The OS is waiting to make sure any delayed packets don't confuse a new connection.

How to fix it

Option 1: Wait 60 seconds. That's the obvious one. Not great when you're iterating fast.

Option 2: Set the SO_REUSEADDR socket option in your code. This tells the OS it's okay to reuse the address even if TIME_WAIT is active. In Node.js with the built-in http module, it's on by default. If you're using raw net or a custom server, do:

const server = net.createServer();
server.listen({ port: 3000, reuseAddr: true });

But honestly, most Node frameworks (Express, Koa, Fastify) already set this. If you're still seeing the error, it's almost certainly Cause #1, not this.

Option 3: Use the wait-on or cross-port-killer npm package. Install it and run it before your server starts:

npx kill-port 3000

That kills whatever's on the port. Then start your server. It's my go-to for development scripts.

Cause #3: Multiple instances of your app started accidentally

You ran node server.js twice, or your process manager (like pm2 or nodemon) started a second instance. This is common when you have a build script that starts the server and also a watcher that starts it again.

How to check

Run the same lsof or netstat command from above. If you see two lines with LISTEN on port 3000, you have two Node processes. Kill both with kill -9 (or taskkill /F) and restart only one.

Preventing it

If you're using nodemon, check your nodemon.json or package.json scripts for duplicate node server.js calls. Common mistake:

"scripts": {
  "start": "nodemon server.js & node server.js"
}

That starts two servers. Remove the extra one.

If you're using pm2, run pm2 list to see all processes. If you have a stale instance, run pm2 delete all and start fresh.

Quick reference summary

CauseSymptomFix
Orphaned process still runningError appears after closing terminal or stopping server incorrectlyFind PID with lsof -i :PORT or netstat, then kill -9 PID
TIME_WAIT stateError appears after clean Ctrl+C, if you restart immediatelyWait 60 seconds, or use reuseAddr: true (usually default), or run npx kill-port
Accidental duplicate serverTwo Node processes listen on the same portKill all Node processes on that port, fix your startup scripts

That's it. Next time you see EADDRINUSE, don't panic. Check if a process is lingering. If not, wait a few seconds or kill the port. You'll be back to coding in under a minute.

Was this solution helpful?