How to Solve ‘Error: listen EADDRINUSE’ in Node.js

Sharing is Caring...

If you’re working with Node.js and run into the error:

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

Don’t panic. This simply means that the port you are trying to use, commonly 3000, 5000, or 8080, is already being used by another process. To fix this, you can either kill the process currently using the port or change the port your app is trying to use. In this guide, we will walk you through every step of the process to fully understand and resolve this issue like a pro.

What Does EADDRINUSE Mean?

EADDRINUSE is a short form for “Error: Address in Use.” The address here refers to a network port on your computer—an interface that allows communication between programs and the system.

When you start a Node.js server using app.listen(PORT) Node tries to bind the server to that port. If that port is already being used by another process (another app, another instance of the same app, or even a zombie process that didn’t close properly), Node throws this error to let you know: “I can not listen on this port because something else is already using it.

Imagine trying to sit in a chair that is already occupied, either you ask the person to get up, or you find another chair.

Common Scenarios Where This Error Occurs

  • You ran your server once, forgot to stop it, and tried running it again.
  • You have multiple Node apps open, all trying to use the same port (e.g., 3000).
  • Another program (e.g., React, Angular, Docker, or even a system app) is using the port.
  • Your app crashed, but the process didn’t terminate properly, leaving the port occupied.
  • Your IDE (like VS Code) auto-restarted your app but didn’t kill the previous instance.

Step-by-Step Guide to Fix EADDRINUSE in Node.js

Let’s fix this error with multiple approaches—from the most direct solution to best practices.

Method 1: Find and Kill the Process Using the Port

Step 1: Check Which Process is Using the Port

Replace 3000 With the port in your error message.

On macOS/Linux:

lsof -i :3000

This lists processes using port 3000.

Example Output:

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

Here, 12345 is the process ID (PID).

On Windows (Command Prompt or PowerShell):

netstat -ano | findstr :3000

Find the PID at the end of the output.

More details: Stack Overflow – How to find what’s using a port

Step 2: Kill the Process

macOS/Linux:

kill -9 12345

Windows:

taskkill /PID 12345 /F

After this, try running your Node.js app again. It should work now.

Method 2: Change the Port in Your Code

A quick and clean solution is to run your server on a different port.

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

Even better, use environment variables:

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

Now you can run the app like this:

PORT=3002 node index.js  # macOS/Linux
$env:PORT=3002; node index.js  # Windows PowerShell

Method 3: Automatically Free Port Before Running the Server

Use the kill-port package:

1. Install globally:

npm install -g kill-port

2. Use it before starting your app:

kill-port 3000 && node index.js

3. Or add it to package.json:

"scripts": {
  "start": "kill-port 3000 && node index.js"
}

Now you can run:

npm start

This is extremely helpful in development when you restart your server often.

Method 4: Handle Server Shutdown Gracefully

If your app crashes and doesn’t release the port, it’s usually because the process is not handling termination properly. You can fix that with a graceful shutdown.

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

process.on('SIGTERM', () => {
  server.close(() => {
    console.log('Process terminated, server closed');
  });
});

process.on('SIGINT', () => {
  server.close(() => {
    console.log('Process interrupted, server closed');
  });
});

Now your app will cleanly exit and release the port on Ctrl + C or system shutdown.

Real-World Example Using Express

Here’s what your index.js might look like using best practices:

const express = require('express');
const app = express();

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

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

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

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

This approach ensures no EADDRINUSE errors even after multiple restarts.

Final Tips, Notes, and Best Practices

  • Always use dynamic ports with process.env.PORT || 3000 In production.
  • Use Nodemon in development for auto-restarting:
npm install --save-dev nodemon

In package.json:

"scripts": {
  "dev": "nodemon index.js"
}
  • Avoid using low-numbered ports (<1024) without admin/root privileges.
  • If all else fails, reboot your machine—but it is a last resort.
  • Keep your development environment clean. Zombie processes often cause port issues.

Conclusion

The EADDRINUSE Error is one of the most common and frustrating issues developers face when working with Node.js. But now that you understand why it happens and how to fix it, you will be able to handle it easily in future projects.

Whether you are a beginner or a seasoned developer, using the strategies outlined in this guide, checking running processes, changing ports, using kill-port, and handling graceful shutdowns, will save you a ton of time and headaches.

If you found this helpful, you may also want to check out: Techonboom.


Sharing is Caring...
Rohit Verma

I’m Rohit Verma, a tech enthusiast and B.Tech CSE graduate with a deep passion for Blockchain, Artificial Intelligence, and Machine Learning. I love exploring new technologies and finding creative ways to solve tech challenges. Writing comes naturally to me as I enjoy simplifying complex tech concepts, making them accessible and interesting for everyone. Always excited about the future of technology, I aim to share insights that help others stay ahead in this fast-paced world

Leave a Comment