You start your dev server and get:

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

Something is already listening on that port. Usually it is a previous dev server that did not shut down cleanly, a second terminal you forgot about or a container publishing the same port.

Find the process using the port

macOS and Linux

bash
lsof -i :3000
# or, on Linux
ss -ltnp | grep :3000

The output shows the command and its PID (process ID).

Windows (PowerShell)

powershell
Get-NetTCPConnection -LocalPort 3000 | Select-Object LocalPort, OwningProcess
Get-Process -Id <PID>

Or in Command Prompt:

bat
netstat -ano | findstr :3000
tasklist /FI "PID eq <PID>"

Stop it

Check what the process is before killing it; it might be something you need.

bash
# macOS / Linux
kill <PID>          # polite
kill -9 <PID>       # force, if it will not stop
powershell
# Windows
Stop-Process -Id <PID>

Use a tool for it

If you hit this often, a small CLI saves time. PortSlayer, for example, finds and frees occupied development ports across platforms:

bash
pip install portslayer

The cross-platform npx kill-port 3000 is another option in Node projects.

Why it keeps happening

  • Dev servers left running in another terminal or editor task.
  • Crashed processes that left a child process alive, such as a watcher spawning the server.
  • Docker containers mapping the same host port (docker ps shows them).
  • Two apps with the same default port: many frameworks default to 3000, 5173 or 8080.

Prevent it

  • Stop dev servers with Ctrl+C rather than closing the terminal window.
  • Make your app read the port from an environment variable so you can change it easily:
javascript
const port = Number(process.env.PORT) || 3000;
app.listen(port, () => console.log(`Listening on ${port}`));
  • Handle shutdown signals so child processes are stopped too:
javascript
process.on("SIGTERM", () => server.close(() => process.exit(0)));
process.on("SIGINT", () => server.close(() => process.exit(0)));
  • Give each project a distinct port in its config.

Key takeaways

  • EADDRINUSE means another process is already listening on the port.
  • Use lsof/ss on macOS and Linux, Get-NetTCPConnection or netstat on Windows.
  • Check the process before killing it.
  • Read the port from an environment variable and handle shutdown signals.