Node.js "EADDRINUSE: address already in use" — Find and Free the Port

Something already listens on that port — usually a previous instance of your own dev server that never died. Find it by port, decide whether to kill it, and add graceful shutdown for next time.

What you'll see

Root causes

Zombie instance of your own app

Ctrl-C during a hung build, nodemon forking, or a detached process: ps aux | grep node shows the straggler holding the port.

Another service legitimately owns the port

Port 3000 is famously fought over (React dev, Grafana, others). lsof -i :3000 -sTCP:LISTEN identifies the real owner before you kill it.

Fix it

  1. Identify the holder
    lsof -i :3000 -sTCP:LISTEN -P -n   # or: ss -tlnp | grep :3000
  2. Kill it if it's yours
    kill <pid>   # stubborn: kill -9 <pid>  (see it: kill -l vs your app's signal handlers)
  3. Prefer a graceful-shutdown handler so Ctrl-C always frees the port
    // app: const srv = app.listen(port); process.on('SIGTERM', () => srv.close(() => process.exit(0))); // + SIGINT
  4. Or make the port configurable and default elsewhere in dev
    PORT=3001 npm start   # package.json scripts: "dev": "PORT=3001 node server.js"

Field note

Dev tip: PORT=0 makes Node pick a free port and log the chosen one (server.address().port). In containers, EADDRINUSE at startup usually means your process forks/clusters with reusePort unset, or two containers map the same host port.

Common questions

I killed the process but the port is still busy. Why?

Either it wasn't the listener (check lsof output — it must show LISTEN state), or the port sits in TIME_WAIT. SO_REUSEADDR (Node sets it by default on listen) handles TIME_WAIT; a hard kill -9 skips your close handlers, so always prefer plain kill.

How do I prevent this in dev teams?

Configurable PORT per developer, graceful SIGTERM/SIGINT handlers, and a predev script that checks/frees the port. Docker dev setups isolate it per container entirely.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.