VMHeaven

Troubleshooting

Address already in use (EADDRINUSE) — free the port

Something already holds the port you want. How to find the process, stop it or switch ports, and handle the TIME_WAIT case after a restart.

Updated 08 Aug 2026~5 min read

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:

who is on the port?
sudo ss -tlnp 'sport = :3000'
# or
sudo lsof -i :3000

Stop 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:

stop the process
kill <PID>        # graceful
kill -9 <PID>     # only if it ignores the first

If it is a managed service you actually want, do not kill it — change your app’s port instead.

Use a different port

pick a free port
# Node
PORT=3001 node server.js

# generic: find a free one first
ss -tlnp | grep :30    # scan the 30xx range

The 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.
Python example
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:

systemd handles the lifecycle
sudo systemctl restart your-app   # stops the old one first

Deploying 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.

More in Troubleshooting

See all