How to Fix EADDRINUSE: Address Already in Use
EADDRINUSE / [Errno 98] Address already in use means a process is already bound to the port you want. Finding and killing that process is a three-command loop. Here's exactly how.
What EADDRINUSE actually means
When your server starts, it asks the OS to bind a port. If anything else is already
listening there - a stale previous run, a python -m http.server left open, a
misrouted service - the OS refuses with OSError: [Errno 98] Address already in use
(EADDRINUSE on Linux, EADDRINUSE / WSAEADDRINUSE on macOS/Windows).
The bug is not in your code. The port is occupied.
Step 1: find what's holding the port
Three commands, any of them works - use whichever is on the box:
ss -ltnp | grep :8000 # modern Linux - shows process name + PID
lsof -i :8000 # classic - shows PID, user, and the full command
fuser 8000/tcp # prints just the PID(s)
ss -ltnp output looks like:
LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* users:(("python3",pid=1842,fd=3))
The pid= field is the culprit. In this case it's PID 1842.
Step 2: kill the process
Once you have the PID:
kill 1842 # graceful SIGTERM
# if it doesn't stop:
kill -9 1842 # SIGKILL - guaranteed
Or let fuser do both steps in one shot:
fuser -k 8000/tcp # finds and SIGKILLs every process on tcp/8000
Verify the port is free before restarting:
ss -ltnp | grep :8000 # should return nothing
Step 3: start your server
python3 app.py
The bind succeeds and your server is up.
Why does this keep happening?
- Stale background processes - a previous
nohup python3 app.py &that didn't get cleaned up. Always track long-running processes or use a process manager. TIME_WAITsockets - after a hard restart the OS holds the port inTIME_WAITfor ~60 s.SO_REUSEADDRin your socket options (Flask/uvicorn enable this by default) bypasses it for most cases.- Port conflicts - two services configured to the same port. Fix the config rather than killing one each time.
Quick reference
| Command | What it does |
|---|---|
ss -ltnp \| grep :PORT |
Shows PID + process name bound to PORT |
lsof -i :PORT |
Shows all processes with open sockets on PORT |
fuser PORT/tcp |
Prints PIDs on PORT |
fuser -k PORT/tcp |
Kills all processes on PORT |
Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.
Try it in a workspace →What you'll practice
- Using ss, lsof, and fuser to find the process holding a port
- Killing a port-occupying process by PID and with fuser -k
- Verifying a port is free before restarting a server
FAQ
What causes 'OSError: [Errno 98] Address already in use'?
Another process is already bound to the port your server is trying to open. The OS won't allow two processes to listen on the same TCP port. You need to find and stop the occupying process, or choose a different port.
How do I find what process is using a port on Linux?
Use ss -ltnp | grep :PORT (shows process name and PID), lsof -i :PORT, or fuser PORT/tcp (prints only the PID). All three work; ss is the modern default on most distros.
How do I kill a process on a port without knowing the PID?
Run fuser -k PORT/tcp - it finds every process listening on that TCP port and sends SIGKILL in one step. Or get the PID from ss/lsof and run kill <pid>.
How do I fix 'port already in use'?
Find the process holding the port with ss -ltnp, lsof -i, or fuser, then kill its PID - your server can bind the port again. Or start the app on a different port.
Keep learning
Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.
Open the workspace →