CalcSnippets Search
Node.js 2 min read

How to Fix EADDRINUSE Address Already in Use Errors on Port 3000 5173 or 8080 Without Rebooting Your Machine

A practical guide to fixing EADDRINUSE and address already in use errors by finding the exact owning process, understanding why it stayed alive, and freeing the right port without killing unrelated work.

Why this problem keeps returning: the port conflict is rarely the whole bug. The real issue is usually an orphaned process, a second dev server, or a watcher that survived after you thought it died.

Typical output:

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

The worst fix is to restart your machine every time this appears. The better fix is to identify the owner and decide whether it should live.

Step 1: find the real process

On macOS or Linux:

lsof -iTCP:3000 -sTCP:LISTEN

For other ports:

lsof -iTCP:5173 -sTCP:LISTEN
lsof -iTCP:8080 -sTCP:LISTEN

If you want just the PID:

lsof -tiTCP:3000 -sTCP:LISTEN

Step 2: inspect before killing

ps -fp "$(lsof -tiTCP:3000 -sTCP:LISTEN)"

This matters because the owner might be:

  1. your actual app in another terminal
  2. a previous watcher process
  3. Docker publishing that port
  4. a different project entirely

Step 3: kill the exact process if appropriate

kill -15 "$(lsof -tiTCP:3000 -sTCP:LISTEN)"

If it ignores SIGTERM:

kill -9 "$(lsof -tiTCP:3000 -sTCP:LISTEN)"

Use -9 only when the process refuses to exit normally.

If Docker owns the port

Check published containers:

docker ps
docker stop <container_id>

Do not keep killing random Node processes if the real owner is a container port mapping.

If the framework can switch ports, use that deliberately

Examples:

PORT=3001 npm run dev
npx next dev -p 3001
vite --port 5174

Changing the port is fine when you know why you are doing it. It is a workaround, not a diagnosis.

Why this happens so often

The most common reasons are boring:

  1. terminal closed but child process survived
  2. auto-reloader forked another process
  3. a second copy of the app is still running
  4. Docker or another local service already claimed the port

Once you get used to checking ownership first, the bug becomes much less dramatic.

Quick verification

lsof -iTCP:3000 -sTCP:LISTEN
npm run dev

If the first command returns nothing and the second starts cleanly, the port is free again.

Bottom line

EADDRINUSE is a process ownership question before it is a framework question. Find the listener, inspect it, then kill or reconfigure it on purpose.

Sources

Keep reading

Related guides