Ffile2fix
Sign in Get started

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

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

Your Node app tried to listen on a port that another process is already listening on, so the operating system refused. Usually that other process is an earlier copy of the same app that never stopped.

Also appears as: Error: listen EADDRINUSE: address already in use 127.0.0.1:8080 · Error: listen EADDRINUSE :::5173 · Port 3000 is already in use · Error: listen EACCES: permission denied 0.0.0.0:80

Common causes

  • A previous run of the dev server is still running in another terminal or in the background
  • A crashed nodemon or ts-node-dev left an orphaned child process
  • PM2 or systemd already runs the app, and you started it again by hand
  • Your code calls app.listen() twice (for example in both app.js and server.js, or in tests)
  • Another program uses the port (another framework's dev server, Docker container, Skype or AirPlay Receiver on 5000/7000 on macOS)

How to fix it

  1. Find the process using the port. On Linux/macOS run lsof -i :3000 (or sudo ss -ltnp | grep 3000). On Windows run netstat -ano | findstr :3000 and note the PID in the last column.
  2. Stop it cleanly. If it is your old dev server, stop it with Ctrl+C in its terminal, or kill <PID> on Linux/macOS, or taskkill /PID <PID> /F on Windows.
  3. Check process managers. Run pm2 list or systemctl status yourapp. If the app is already managed there, restart it with pm2 restart yourapp instead of launching another copy.
  4. Look for a double listen(). Search the code for .listen(. In tests, export the app without calling listen and let Supertest open its own port.
  5. Make the port configurable. Read the port from process.env.PORT with a fallback so you can run PORT=3001 npm start, and so hosts like cPanel/Passenger can assign one.
  6. Shut down gracefully. Handle SIGINT and SIGTERM and call server.close() so restarts by nodemon or PM2 release the port.

server.js

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

for (const sig of ['SIGINT', 'SIGTERM']) {
  process.on(sig, () => server.close(() => process.exit(0)));
}

How to stop it happening again

  • Run one instance per port and manage production processes with PM2 or systemd only
  • Always read the port from an environment variable
  • Close the server on SIGINT/SIGTERM so watchers can restart cleanly

Frequently asked questions

What does ':::3000' mean?

'::' is the IPv6 'all addresses' notation, meaning Node tried to listen on port 3000 on every interface. Any process listening on that port, IPv4 or IPv6, can block it.

How do I kill whatever is on the port in one command?

On Linux/macOS, kill $(lsof -t -i:3000) stops it. Check what it is first so you do not stop a database or another important service by accident.

Why do I get EACCES on port 80 instead?

Ports below 1024 need elevated privileges on Linux. Run the app on a high port such as 3000 and put Nginx or Apache in front of it as a reverse proxy.