What's Actually Happening

When you try to start the SSH daemon, it fails because another process is already listening on port 22. This prevents the SSH service from binding to the default SSH port and accepting connections.

The Error You'll See

In your system logs or when manually starting sshd, you'll see:

bash
error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
fatal: Cannot bind any address.

Or in systemd journal:

bash
sshd[1234]: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
systemd[1]: sshd.service: Main process exited, code=exited, status=255/EXCEPTION

Why This Happens

Port 22 can be occupied by another SSH instance, a different service, or a stuck process. Common causes include an already-running SSH daemon, a misconfigured service file starting SSH twice, or another application configured to use port 22. Less commonly, a socket may remain in TIME_WAIT state after a recent service stop.

Step 1: Identify What's Using Port 22

Find the process occupying port 22:

bash
sudo lsof -i :22

Or using ss:

bash
sudo ss -tlnp | grep :22

Or using netstat:

bash
sudo netstat -tlnp | grep :22

Note the PID (process ID) from the output.

Step 2: Check for Duplicate SSH Processes

Sometimes SSH itself is running from a different configuration:

bash
ps aux | grep sshd

You might see multiple sshd processes or a process started with a different config file.

Step 3: Stop the Conflicting Process

If it's an SSH daemon that shouldn't be running:

bash
sudo systemctl stop sshd

Or if it's a different service entirely, stop it:

bash
sudo systemctl stop conflicting-service

For a stuck process that won't stop normally:

bash
sudo kill -9 <PID>

Step 4: Check for Services Configured for Port 22

Search for other services configured to use port 22:

bash
sudo grep -r "Port 22" /etc/

Check systemd socket activation:

bash
sudo systemctl list-sockets | grep 22

Step 5: Handle Socket in TIME_WAIT State

If the port appears free but still won't bind, check for sockets in TIME_WAIT:

bash
sudo ss -tan | grep :22

If you see TIME_WAIT, wait 60 seconds for it to clear, or adjust kernel settings:

```bash # View current settings sudo sysctl net.ipv4.tcp_fin_timeout

# Temporarily reduce timeout (use with caution) sudo sysctl -w net.ipv4.tcp_fin_timeout=30 ```

Step 6: Change SSH Port (Alternative Solution)

If you want to run SSH on a different port alongside another service, edit /etc/ssh/sshd_config:

bash
Port 2222

Then restart SSH:

bash
sudo systemctl restart sshd

Remember to update firewall rules and any port-forwarding configurations.

Verify the Fix

After stopping the conflicting process, start the SSH service:

bash
sudo systemctl start sshd
sudo systemctl status sshd

Verify it's listening:

bash
sudo ss -tlnp | grep :22

Test the connection:

bash
ssh user@localhost

If you changed the port, specify it:

bash
ssh -p 2222 user@localhost

The service should start without errors and accept connections normally.