Address already in use — shown as EADDRINUSE in Node, bind() failed in nginx, or OSError: [Errno 98] in Python — means the port you want is already taken. Something is listening on it, and only one process can bind a port at a time. Find that process; then either stop it or use a different port.
Find what is holding the port
Replace 3000 with your port. This prints the process name and PID:
sudo ss -tlnp 'sport = :3000'
# or
sudo lsof -i :3000Stop it — or realise it is what you meant to run
Very often it is a previous copy of your own app that did not exit cleanly. End it:
kill <PID> # graceful
kill -9 <PID> # only if it ignores the firstIf it is a managed service you actually want, do not kill it — change your app’s port instead.
Use a different port
# Node
PORT=3001 node server.js
# generic: find a free one first
ss -tlnp | grep :30 # scan the 30xx rangeThe subtle case: TIME_WAIT after a restart
If you just stopped the app and an immediate restart still fails, the socket may be inTIME_WAIT — the kernel holds it briefly after close. Two fixes:
- Wait 30–60 seconds and start again.
- Enable address reuse in your app so restarts are instant. In Node, the default server already sets it; in custom C/Python sockets, set
SO_REUSEADDR.
import socket
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0", 3000))Prevent it with a process manager
Zombie copies that hog ports usually come from starting apps by hand. Run them under systemd or a process manager so a restart cleanly replaces the old instance:
sudo systemctl restart your-app # stops the old one firstDeploying several services on one box? A KVM VPS with a dedicated public IP lets you map ports cleanly instead of fighting over them.
Frequently asked
How do I find what is using a port?
Run 'sudo ss -tlnp "sport = :3000"' or 'sudo lsof -i :3000'. It prints the process name and PID holding the port.
The port is free but the restart still fails — why?
The socket may be in TIME_WAIT for a short while after close. Wait 30–60 seconds, or set SO_REUSEADDR in your app so restarts are instant.
Why do I get permission denied instead on port 80?
Ports below 1024 need root to bind. Run behind nginx, or grant the capability with setcap rather than running the app as root.