Common Issues
Port Already in Use
Find and resolve "Address already in use" errors when a service fails to start because another process is bound to the same port.
"Address already in use" or EADDRINUSE errors occur when a process tries to bind to a port that's already occupied.
Find What Is Using a Port
# ss (modern, fast - recommended)
ss -tlnp | grep :80
ss -tlnp | grep :3000
# lsof
lsof -i :80
lsof -i TCP:443
# fuser
fuser 80/tcp
fuser 3306/tcp
# netstat (legacy, still common)
netstat -tlnp | grep :80Output from ss:
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))Kill the Process on a Port
# Kill by port (fuser)
fuser -k 80/tcp
fuser -k 443/tcp
# Kill by PID (from ss/lsof output)
kill 1234
kill -9 1234 # force kill if unresponsiveCommon Scenarios
Two Nginx/Apache Instances
# Check how many nginx processes are listening
ss -tlnp | grep nginx
# List all nginx processes
ps aux | grep nginx
# Stop all and restart cleanly
systemctl stop nginx
pkill nginx
systemctl start nginxNode.js App Already Running
# Check PM2 processes
pm2 list
pm2 stop myapp
# Also kill any leftover node processes on the port
fuser -k 3000/tcpDocker Port Conflict
# Find which container uses port 80
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep :80
# Stop the conflicting container
docker stop container_name
# Or change the host port mapping in docker-compose.yml
ports:
- "8080:80" # map to 8080 insteadMySQL Duplicate Instance
# Check for multiple mysqld processes
ps aux | grep mysqld
# Only one instance should run
systemctl stop mysql
pkill mysqld
systemctl start mysqlTIME_WAIT Sockets
Sometimes ss shows a socket in TIME_WAIT state, this is not a running process. The kernel holds the socket for 60 seconds after connection close to prevent stale packets.
# View TIME_WAIT sockets
ss -tn state time-wait | head -20
# Count them
ss -tn state time-wait | wc -lIf TIME_WAIT sockets are blocking your app from restarting, reduce reuse time:
# Allow reuse of TIME_WAIT sockets (safe for most servers)
sysctl net.ipv4.tcp_tw_reuse=1
# Reduce TIME_WAIT timeout (default 60s)
sysctl net.ipv4.tcp_fin_timeout=30
# Persistent
echo "net.ipv4.tcp_tw_reuse=1" >> /etc/sysctl.d/99-network.conf
echo "net.ipv4.tcp_fin_timeout=30" >> /etc/sysctl.d/99-network.conf
sysctl -p /etc/sysctl.d/99-network.confSystemd: Always Use systemctl
Never start services both manually and via systemd, they'll conflict:
# Wrong: starts a second instance
./myapp &
systemctl start myapp
# Right: use systemctl only
systemctl start myapp
systemctl restart myappCheck What Port a Service Will Use Before Starting
# Nginx
nginx -T | grep listen
# Apache
apache2ctl -S
# Custom app: check its config file
grep -r "port\|listen\|bind" /etc/myapp/config.ymlUseful One-Liner: Free Up a Port
# Find and kill whatever is on port 8080
kill $(lsof -t -i:8080)
# Safer version (asks for confirmation)
lsof -i :8080
kill $(lsof -ti :8080)Never blindly kill processes without identifying them first. Killing a critical database or system process can cause data loss or system instability.