How to Fix EADDRINUSE in Node.js (2025)

The definitive guide to fixing "address already in use" errors across every Node.js framework.

8 min read · Updated January 2025

What is EADDRINUSE?

Error: listen EADDRINUSE: address already in use :::3000 means another process is already listening on the port your application is trying to bind to. This is one of the most common errors in Node.js development.

The error code breaks down as:

Quick Fix: One Command

The fastest way to fix EADDRINUSE is with portrm:

# Find and kill whatever is on port 3000
$ npx portrm fix 3000

# Or kill and restart your dev server in one step
$ npx portrm fix 3000 --run "npm run dev"

No need to look up PIDs, no risk of killing the wrong process. portrm identifies the service, checks if it is safe to kill, and handles the cleanup.

No install required. npx portrm runs without installing anything globally. Or install it once: npm i -g portrm

Why EADDRINUSE Happens

The most common causes:

1. A previous server did not shut down

You pressed Ctrl+C but the process is still running in the background. This happens frequently with tools that spawn child processes (Webpack, Vite, Next.js).

2. Hot reload created a zombie process

Your file watcher restarted the server but the old instance did not exit. Common with nodemon, ts-node-dev, and similar tools.

3. Another tool is using the port

Docker, another dev server, or a database is already bound to the port.

4. TIME_WAIT socket state

After a process exits, the OS keeps the port in TIME_WAIT for 30-60 seconds. This is less common but can cause issues during rapid restarts.

Framework-Specific Fixes

Express.js

# Error:
Error: listen EADDRINUSE: address already in use :::3000

# Fix:
$ ptrm fix 3000 --run "node server.js"

Prevention: add graceful shutdown to your Express app:

const server = app.listen(3000);
process.on('SIGTERM', () => server.close());
process.on('SIGINT', () => server.close());

Next.js

# Error:
ready - started server on 0.0.0.0:3000
Error: listen EADDRINUSE: address already in use :::3000

# Fix:
$ ptrm fix 3000 --run "npm run dev"

# Or use a different port:
$ npx next dev -p 3001

Vite

# Error:
Error: Port 5173 is already in use

# Fix:
$ ptrm fix 5173 --run "npm run dev"

Vite defaults to port 5173. You can change it in vite.config.ts:

export default defineConfig({
  server: { port: 3000, strictPort: false }
});

Setting strictPort: false tells Vite to try the next available port instead of failing.

NestJS

# Fix:
$ ptrm fix 3000 --run "npm run start:dev"

Fastify

# Fix:
$ ptrm fix 3000 --run "node server.js"

Manual Fix by Operating System

macOS / Linux

# Find the process
$ lsof -i :3000
COMMAND  PID  USER  FD   TYPE DEVICE SIZE/OFF NODE NAME
node    1234  user  23u  IPv6 ...    0t0      TCP *:3000

# Kill it
$ kill -9 1234

Windows

# Find the process
> netstat -ano | findstr :3000
  TCP  0.0.0.0:3000  0.0.0.0:0  LISTENING  1234

# Kill it
> taskkill /PID 1234 /F

Preventing EADDRINUSE

1. Handle graceful shutdown

Always close your server on SIGTERM and SIGINT signals. This ensures the port is released when you stop the process.

2. Use portrm in your npm scripts

{
  "scripts": {
    "dev": "ptrm fix 3000 -y && next dev",
    "predev": "ptrm fix 3000 -y"
  }
}

3. Use a .ptrm.toml config

[project]
name = "my-app"

[services.frontend]
port = 3000
run = "npm run dev"
preflight = true

4. Set strictPort to false

Vite, Next.js, and other frameworks can auto-increment to the next available port instead of crashing.

Stop fighting EADDRINUSE

Install portrm and fix port conflicts in one command.