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

Output 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 unresponsive

Common 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 nginx

Node.js App Already Running

# Check PM2 processes
pm2 list
pm2 stop myapp

# Also kill any leftover node processes on the port
fuser -k 3000/tcp

Docker 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 instead

MySQL Duplicate Instance

# Check for multiple mysqld processes
ps aux | grep mysqld

# Only one instance should run
systemctl stop mysql
pkill mysqld
systemctl start mysql

TIME_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 -l

If 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.conf

Systemd: 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 myapp

Check 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.yml

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

On this page