If you see a bind: address already in use or EADDRINUSE error when starting a server, another process is already occupying that port.
Finding the occupying process
ss (recommended — installed by default on most systems)
Bash
# Check occupancy of a specific port (e.g. 3000)
sudo ss -tlnp | grep :3000
# Example output
# LISTEN 0 511 0.0.0.0:3000 0.0.0.0:* users:(("node",pid=12345,fd=22))
# ↑ process name ↑ PIDBash
# View all LISTEN ports and processes at once
sudo ss -tlnplsof
Bash
sudo lsof -i :3000
# Example output
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# node 12345 deploy 22u IPv4 123456 0t0 TCP *:3000 (LISTEN)fuser
Bash
sudo fuser 3000/tcp
# Output: 3000/tcp: 12345 ← PIDAfter identifying the process
Bash
# Identify the process by PID
ps -p 12345 -o pid,ppid,user,comm,args
# Check the executable path
ls -la /proc/12345/exeMethod 1: When managed as a service
Bash
# Check the service name
sudo systemctl status 12345 # When it's hard to find by PID
# or
cat /proc/12345/comm # process name
# Restart the service
sudo systemctl restart myapp
# or fully stop then start
sudo systemctl stop myapp
sudo systemctl start myappMethod 2: Killing a leftover process
Bash
# Graceful shutdown (SIGTERM)
sudo kill 12345
# Force-kill if still running after 3 seconds
sleep 3 && sudo kill -9 12345
# Kill all processes matching a name
sudo pkill -f "node server.js"Method 3: Change the port (without killing the process)
Bash
# Example: change the port in the app config (Node.js)
# PORT=3001 node server.js
# or edit the environment file
# .env: PORT=3001
# Change Nginx/Apache config
sudo nano /etc/nginx/sites-available/mysite
# listen 3001; ← change, then reload
sudo nginx -t && sudo systemctl reload nginxWhen the port is occupied in TIME_WAIT state
This happens when the port still won't open even after you killed the process.
Bash
# Check TIME_WAIT state
sudo ss -tn | grep TIME-WAIT | grep :3000
# Check wait timeout (default 60 seconds)
cat /proc/sys/net/ipv4/tcp_fin_timeoutQuick fix — use the SO_REUSEADDR option (in app code):
Node.js example:
JavaScript
server.listen({ port: 3000, host: '0.0.0.0' }, () => {});
// add reuseAddr: true to the server options (net module)Quick fix — shorten kernel TIME_WAIT:
Bash
# Apply immediately (resets after reboot)
sudo sysctl -w net.ipv4.tcp_fin_timeout=15
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
# Persist across reboots
echo "net.ipv4.tcp_fin_timeout = 15" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_tw_reuse = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -pSummary
| Situation | Command |
|---|---|
| Find occupying process | `sudo ss -tlnp |
| Identify process by PID | ps -p PID -o comm,args |
| Graceful shutdown | sudo kill PID |
| Force kill | sudo kill -9 PID |
| TIME_WAIT wait | sudo sysctl -w net.ipv4.tcp_fin_timeout=15 |
Editorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Questions & answers
Ask a question about this guide. We'll review and reply.