Back

Fix Error: 'listen EADDRINUSE: address already in use' in Node.js

Fix Error: 'listen EADDRINUSE: address already in use' in Node.js

The dreaded EADDRINUSE error strikes when you least expect it. You’re ready to start your Node.js server, but instead of a running application, you get: Error: listen EADDRINUSE: address already in use :::3000. This Node.js EADDRINUSE error means another process is already using the port you’re trying to bind to. Here’s how to identify and fix this port conflict in Node.js quickly.

Key Takeaways

  • The EADDRINUSE error occurs when a port is already occupied by another process
  • Use lsof on macOS/Linux or netstat on Windows to identify the blocking process
  • Kill the process using its PID or implement graceful shutdown handlers
  • Prevent future conflicts with dynamic port selection and proper signal handling

What Causes the EADDRINUSE Error?

The listen EADDRINUSE error occurs when your Node.js application tries to bind to a port that’s already occupied. Common culprits include:

  • A previous instance of your server still running
  • Another application using the same port
  • Zombie processes from crashed Node.js apps
  • Hot-reload tools like nodemon failing to clean up
  • IDE integrated terminals keeping processes alive

How to Find Which Process Is Using the Port

Before you can free the occupied port, you need to identify what’s using it. The commands differ by operating system.

macOS and Linux

Use lsof to find the process:

lsof -i :3000

This returns process details including the PID (Process ID):

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

Windows

Use netstat to identify the process:

netstat -ano | findstr :3000

Output shows the PID in the last column:

TCP    0.0.0.0:3000    0.0.0.0:0    LISTENING    12345

How to Kill the Process and Free the Port

Once you have the PID, you can terminate the process to free the port.

macOS and Linux Solutions

Quick one-liner:

lsof -ti:3000 | xargs kill -9

Manual approach:

kill -15 12345  # Graceful shutdown (preferred)
kill -9 12345   # Force kill if -15 doesn't work

Alternative using fuser:

sudo fuser -k 3000/tcp

Windows Solutions

Command Prompt:

taskkill /PID 12345 /F

PowerShell:

Stop-Process -Id 12345 -Force

GUI Method: Open Task Manager (Ctrl+Shift+Esc), find the Node.js process, and end it.

Preventing Future Port Conflicts

Implement Graceful Shutdown

Add proper cleanup handlers to your Node.js server to prevent port errors:

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

// Handle termination signals
process.on('SIGTERM', () => {
  server.close(() => {
    console.log('Server closed gracefully');
    process.exit(0);
  });
});

process.on('SIGINT', () => {
  server.close(() => {
    console.log('Server closed gracefully');
    process.exit(0);
  });
});

Use Dynamic Port Selection

Avoid hardcoding ports. Use environment variables or find an available port automatically:

const PORT = process.env.PORT || 3000;

// Or check port availability before binding
const net = require('net');

function getAvailablePort(startPort) {
  return new Promise((resolve) => {
    const server = net.createServer();
    server.listen(startPort, () => {
      const port = server.address().port;
      server.close(() => resolve(port));
    });
    server.on('error', () => {
      getAvailablePort(startPort + 1).then(resolve);
    });
  });
}

Handle the Error Programmatically

Catch the error and respond appropriately:

server.on('error', (err) => {
  if (err.code === 'EADDRINUSE') {
    console.error(`Port ${PORT} is already in use`);
    // Try another port or exit gracefully
    process.exit(1);
  }
});

Common Scenarios and Quick Fixes

Nodemon Not Releasing Ports

If using nodemon, ensure you’re stopping it with Ctrl+C, not Ctrl+Z. The latter suspends the process without releasing the port.

Docker Container Conflicts

Check for running containers:

docker ps
docker stop <container_id>

VS Code Terminal Issues

Close all integrated terminals before restarting your server. Sometimes VS Code keeps processes alive in the background.

Multiple Server Instances in Code

Ensure you’re not calling app.listen() multiple times in your codebase. This common mistake triggers the address already in use error immediately.

Conclusion

The Node.js EADDRINUSE error is frustrating but easily fixable. Find the process using your port with lsof or netstat, kill it, and implement proper shutdown handlers to prevent future occurrences. Remember: graceful shutdowns with signal handlers and dynamic port selection will save you from repeatedly dealing with this Node.js server port error.

FAQs

Yes, you can implement automatic port switching by catching the EADDRINUSE error and trying the next available port. Use a recursive function or loop to test ports sequentially until finding an open one, or use libraries like portfinder that handle this automatically.

Closing a terminal window doesn't always terminate running processes. Background processes, especially those started with nohup or as services, continue running. Always use proper termination commands like Ctrl+C or explicitly kill the process using its PID to ensure the port is released.

Using kill -9 forces immediate termination without allowing cleanup, which can cause data loss or corruption. Always try kill -15 first for graceful shutdown. Reserve kill -9 for unresponsive processes. Implement proper signal handlers in your code to ensure clean shutdowns.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay