Fix EADDRINUSE: address already in use
EADDRINUSE means another process is already listening on the port your server wants. Nine times out of ten it is a dev server you started earlier and forgot, or one that a tool started for you. Find it and stop it, or start yours on another port.
Updated . Applies to macOS.
What the error means
When a server starts it asks the operating system to bind a port. If any other process already owns that port, the kernel refuses with EADDRINUSE. Node prints it like this:
Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenHandle [as _listen2] (node:net:1908:16)
at listenInCluster (node:net:1965:12)Other stacks report the same condition in their own words:
- Python:
OSError: [Errno 48] Address already in useon macOS (errno 98 on Linux) - Rails / Puma:
Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE) - Go:
listen tcp :8080: bind: address already in use
The :::3000 in Node's message is the IPv6 wildcard address, not a typo. The port is what matters.
Why the port is taken
Most likely first:
- The same project is already running in another terminal tab, an editor terminal, or a window you closed without stopping the server.
- A coding agent started it. Claude Code, Cursor, Codex and similar tools launch dev servers and preview builds to check their work and do not always stop them.
- A crashed parent left a child alive.
npm run devdied, but thenodeprocess it spawned kept the port. - Another project uses the same default port. Every Next.js app wants 3000, every Vite app 5173.
- A Docker container publishes the port.
lsofshows the owner ascom.docker.backend. - On ports 5000 and 7000, it is macOS itself. AirPlay Receiver listens there. See port 5000 and 7000 on Mac.
Fix 1: find the process and stop it
Show who owns the port, then send it SIGTERM:
lsof -nP -iTCP:3000 -sTCP:LISTEN
kill <PID>Or in one line:
kill $(lsof -ti tcp:3000 -sTCP:LISTEN)If it is still there a second later, kill -9 it. The details, a reusable shell function and what to do when the process keeps coming back are in how to kill the process on a port on Mac.
Fix 2: start yours on another port
When the other server is doing something useful, leave it alone and move. Most tools take a flag or read PORT:
| Tool | Command | Note |
|---|---|---|
| Next.js | next dev -p 3001 | Also picks the next free port by itself and prints a warning. |
| Vite | vite --port 5174 | Picks the next free port unless strictPort is set. |
| Node servers, Create React App | PORT=3001 npm start | Anything that reads process.env.PORT. |
| Rails | bin/rails server -p 3001 | |
| Django | python manage.py runserver 8001 | |
| Flask | flask run -p 5001 | Port 5000 is usually AirPlay, see below. |
| FastAPI / Uvicorn | uvicorn main:app --port 8001 | |
| Python http.server | python3 -m http.server 8001 |
Two projects that must run at once deserve fixed, different ports in their .env or scripts so this stops being a daily event.
Fix 3: stop leaving servers behind
- Stop servers with Ctrl+C in their tab instead of closing the tab or window. Closing often leaves the child process running.
- Avoid backgrounding a dev server with
&unless you also note its PID. Backgrounded servers outlive the shell. - After a coding agent session, list the listeners:
lsof -nP -iTCP -sTCP:LISTEN. Anything you did not start yourself can go. - Keep a counter in the menu bar. Port Monitor shows how many dev ports are busy right now, so a leftover server is visible before you hit the error.
EADDRINUSE right after a clean stop
Rarely, the port stays reserved for a short while after the old server exits, while the kernel finishes closing connections. Node's listen sockets are set up to reuse such addresses, so this is uncommon with Node; if it happens with another runtime, wait half a minute and start again, or confirm with lsof that nothing is actually listening.