How to fix Error: listen EADDRINUSE: address already in use :::3000 in Node.js

Node.jsBEGINNERMEDIUMUpdated Dec 9, 2025ยท 248 views

This error occurs when you try to start a Node.js server on a port that is already occupied by another process. The system refuses to bind to the port because another application is already listening on it.

Quick fix

Fixes EADDRINUSE

lsof -i :3000
  1. Find the process using the port
  2. Kill the process using the port
  3. Use the kill-port package (cross-platform solution)
  4. Change the port in your application
node.js โ€” error
lsof -i :3000
Error: listen EADDRINUSE: address already in use :::3000

What this error means

The EADDRINUSE (Error ADDRess In USE) error is thrown by the Node.js runtime when your application attempts to listen on a TCP port that is already bound to another process. This is a system-level error that prevents multiple processes from listening on the same network address and port combination. When you start a Node.js server using `server.listen()` or `app.listen()`, the operating system tries to reserve that port for your application. If another process has already claimed that port, the OS denies the request and Node.js throws this error. This is a common issue in development environments where developers frequently start and stop servers, sometimes leaving zombie processes running in the background.

Typical symptoms

  • Server fails to start with "EADDRINUSE" error message
  • Error message shows the specific port number that is occupied (e.g., :::3000)
  • Application crashes immediately after attempting to listen on a port
  • Previous server instance appears to still be running in the background
  • Port conflict when running multiple development servers simultaneously
  • nodemon or other file watchers fail to restart the server properly

Common causes

  1. Another instance of your Node.js application is already running on the same port
  2. A previous server process was not properly terminated and is still holding the port
  3. Another application (different from your Node.js app) is using the port
  4. Your IDE or development tool automatically started multiple instances of the server
  5. A crashed Node.js process left the port in a bound state without releasing it
  6. System did not release the port quickly enough after a recent process termination
  7. Multiple Express or HTTP server instances are being created in your code
  8. Port number is hardcoded and conflicts with another service on your system

How to fix "Error: listen EADDRINUSE: address already in use :::3000"

1Find the process using the port

First, identify which process is occupying the port. The commands differ by operating system.

On macOS/Linux:

bash
lsof -i :3000

This will show output like:

bash
COMMAND   PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    12345  user   23u  IPv6  0x...      0t0  TCP *:3000 (LISTEN)

Note the PID (Process ID) shown in the output.

On Windows (Command Prompt or PowerShell):

cmd
netstat -ano | findstr :3000

This shows output like:

bash
TCP    0.0.0.0:3000    0.0.0.0:0    LISTENING    12345

The last number (12345) is the PID.

2Kill the process using the port

Once you have the PID, terminate the process.

On macOS/Linux:

bash
kill -9 12345

Or kill all Node.js processes on that port:

bash
lsof -ti :3000 | xargs kill -9

On Windows (as Administrator):

cmd
taskkill /PID 12345 /F

Or kill all Node.js processes:

cmd
taskkill /F /IM node.exe

After killing the process, try starting your server again.

3Use the kill-port package (cross-platform solution)

Install the kill-port package for a simple, cross-platform way to free up ports:

bash
npm install -g kill-port

Then use it to kill the process on a specific port:

bash
kill-port 3000

Or use it as a dev dependency and add to your package.json scripts:

json
{
  "scripts": {
    "predev": "kill-port 3000",
    "dev": "nodemon server.js"
  }
}

This automatically frees the port before starting your development server.

4Change the port in your application

If you cannot free up the port or prefer to use a different one, modify your application to listen on an alternative port.

Using environment variables (recommended):

javascript
const PORT = process.env.PORT || 3001;

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Then start your app with:

bash
PORT=3001 npm start

Hardcoded alternative (not recommended for production):

javascript
app.listen(3001, () => {
  console.log('Server running on port 3001');
});

This allows your application to run without conflicting with the process on port 3000.

5Add error handling to your server code

Implement proper error handling to detect and respond to port conflicts gracefully:

javascript
const server = app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

server.on('error', (err) => {
  if (err.code === 'EADDRINUSE') {
    console.error(`Port ${PORT} is already in use`);
    console.log('Please kill the process or use a different port');
    process.exit(1);
  } else {
    throw err;
  }
});

Or try alternative ports automatically:

javascript
function startServer(port) {
  const server = app.listen(port, () => {
    console.log(`Server running on port ${port}`);
  });

  server.on('error', (err) => {
    if (err.code === 'EADDRINUSE') {
      console.log(`Port ${port} busy, trying ${port + 1}`);
      startServer(port + 1);
    }
  });
}

startServer(3000);

Advanced notes

Port Binding and TIME_WAIT State:
When a TCP connection closes, the port may remain in a TIME_WAIT state for 30-120 seconds depending on your OS. This prevents immediate reuse to ensure all packets from the previous connection are handled. If you're repeatedly stopping and starting your server, you might encounter this. The SO_REUSEADDR socket option can help, but Node.js HTTP servers don't expose this directly.

Docker and Port Mapping:
If running Node.js in Docker, ensure you're mapping ports correctly with -p flags and that the container's internal port doesn't conflict with other containers. Also verify that your host machine's port is available.

Multiple Server Instances in Code:
Ensure your application code doesn't accidentally create multiple HTTP server instances. This can happen when using file watchers or when importing server creation code multiple times without proper singleton patterns.

Development Tool Conflicts:
IDEs like VS Code with debugger configurations or tools like Webpack Dev Server may occupy common ports (3000, 8080). Check your IDE's running processes and terminal sessions.

Production Considerations:
In production, use process managers like PM2, systemd, or Docker that properly handle process lifecycle and prevent orphaned processes. Always use environment variables for port configuration to avoid hardcoded conflicts.

Alternative: detect-port package:
The detect-port npm package can programmatically find an available port:

javascript
const detect = require('detect-port');

detect(3000).then(port => {
  if (port === 3000) {
    console.log('Port 3000 is available');
  } else {
    console.log(`Port 3000 is in use, using ${port} instead`);
  }
  app.listen(port);
});

Frequently asked questions

What does "EADDRINUSE" mean?
js runtime when your application attempts to listen on a TCP port that is already bound to another process. This is a system-level error that prevents multiple processes from listening on the same network address and port combination. listen(), the operating system tries to reserve that port for your application.
How do I fix "EADDRINUSE"?
This error occurs when you try to start a Node.js server on a port that is already occupied by another process. The system refuses to bind to the port because another application is already listening on it.
What causes "EADDRINUSE"?
Another instance of your Node.js application is already running on the same port A previous server process was not properly terminated and is still holding the port Another application (different from your Node.js app) is using the port
Is the "EADDRINUSE" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading