Fix: Port 3000 Is Already in Use (EADDRINUSE)
The Error
You start your development server and get one of these errors:
Node.js / Express:
Error: listen EADDRINUSE: address already in use :::3000React (create-react-app):
Something is already running on port 3000.Next.js:
Port 3000 is already in use.
Use `next dev --port` to specify a different port.All of these mean the same thing: something else on your machine is already listening on port 3000.
Why This Happens
Port 3000 can only be used by one process at a time. Common causes:
- A previous dev server is still running. You closed the terminal tab but the process didn’t stop.
- Another project is using the same port. You have two apps both defaulting to port 3000.
- A zombie Node.js process. The process crashed but didn’t release the port.
- A Docker container is mapping a container port to 3000 on your host machine.
- A system or background service (like a database admin panel) is bound to that port.
Fix 1: Find and Kill the Process (macOS / Linux)
Find which process is using port 3000:
lsof -i :3000You’ll see output like:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 12345 you 23u IPv6 0x1234 0t0 TCP *:3000 (LISTEN)Kill the process using its PID. First try a graceful shutdown:
kill 12345If the process doesn’t stop after a few seconds, force-kill it:
kill -9 12345One-liner — find and kill in a single command:
lsof -ti :3000 | xargs killThe -t flag makes lsof output only the PID, which is piped directly to kill. Use xargs kill -9 instead if the graceful kill doesn’t work.
Fix 2: Find and Kill the Process (Windows)
Find which process is using port 3000:
netstat -ano | findstr :3000You’ll see output like:
TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12345The last number (12345) is the PID. Kill it:
taskkill /PID 12345 /FOne-liner using PowerShell:
Stop-Process -Id (Get-NetTCPConnection -LocalPort 3000).OwningProcess -ForceFix 3: Use npx kill-port (Cross-Platform)
The simplest solution that works on macOS, Linux, and Windows:
npx kill-port 3000You can kill multiple ports at once:
npx kill-port 3000 3001 8080No global install required — npx downloads and runs it on the fly.
Fix 4: Change the Default Port
If you’d rather keep whatever is on port 3000 running, change your app’s port instead.
React (create-react-app):
PORT=3001 react-scripts startOn Windows (cmd):
set PORT=3001 && react-scripts startOr use cross-env for a cross-platform solution in package.json:
{
"scripts": {
"start": "cross-env PORT=3001 react-scripts start"
}
}Next.js:
npx next dev --port 3001Or in package.json:
{
"scripts": {
"dev": "next dev --port 3001"
}
}Express:
Change the port in your code:
const port = process.env.PORT || 3001;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});Then either edit the fallback value or set the environment variable:
PORT=3001 node server.jsVite:
npx vite --port 3001Or in vite.config.js:
export default defineConfig({
server: {
port: 3001,
},
});Still Not Working?
Multiple Node Processes Are Running
Sometimes several zombie Node processes pile up. Kill them all at once:
macOS / Linux:
killall nodeWindows (cmd):
taskkill /IM node.exe /FWarning: This kills every Node.js process on your machine, including unrelated ones.
A Docker Container Is Using the Port
Check if a Docker container has port 3000 mapped:
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep 3000If you find one, stop it:
docker stop <container_name>Or remove the port mapping by changing -p 3000:3000 to a different host port (e.g. -p 3001:3000) when you run the container.
A System Process Is Using the Port
If lsof or netstat shows a system process (not Node) on port 3000, don’t kill it blindly. Check what it is first:
macOS / Linux:
lsof -i :3000Look at the COMMAND column. If it’s something like Grafana, a database admin panel, or another known service, either disable that service or change your app’s port instead (see Fix 4).
On macOS, AirPlay Receiver is known to occupy port 5000 (not 3000), but it’s worth checking if any macOS system service is using your port. You can disable AirPlay Receiver under System Settings > General > AirDrop & Handoff > AirPlay Receiver if it conflicts with other projects.
The Port Is Freed but the Error Persists
After killing the process, if you still get the error, wait a few seconds. The OS may keep the port in a TIME_WAIT state briefly. If it persists:
macOS / Linux — check if anything is still holding it:
lsof -i :3000If the output is empty and the error continues, restart your terminal or IDE. Some tools cache the port assignment.
Related: If you’re seeing npm dependency errors when setting up your project, see Fix: npm ERR! ERESOLVE unable to resolve dependency tree.
Related Articles
Fix: ERR_CONNECTION_REFUSED (localhost refused to connect)
How to fix 'ERR_CONNECTION_REFUSED', 'localhost refused to connect', and 'This site can't be reached' errors when accessing localhost in Chrome, Firefox, and Edge. Covers dev servers, port issues, 0.0.0.0 vs 127.0.0.1, Docker port mapping, WSL2, firewalls, and more.
Fix: process.env.VARIABLE_NAME Is Undefined (Node.js, React, Next.js, Vite)
How to fix 'process.env.VARIABLE_NAME is undefined' and environment variables not loading from .env files in Node.js, React, Next.js, Vite, and Docker.
Fix: Next.js Image Optimization Errors – Invalid src, Missing Loader, or Unoptimized
How to fix Next.js Image component errors including 'Invalid src prop', 'hostname not configured', missing loader, and optimization failures in production.
Fix: React useEffect runs infinitely (infinite loop / maximum update depth exceeded)
How to fix useEffect infinite loops in React — covers missing dependency arrays, referential equality, useCallback, unconditional setState, data fetching cleanup, event listeners, useRef, previous value comparison, and the exhaustive-deps lint rule.