When ssh fails, the error message already tells you at which stage the connection broke: the network, the SSH service, the key exchange or authentication. In this tutorial you will work through those stages in order, starting from your local machine and then, if needed, from the server's web console. The server-side commands target Ubuntu 24.04 LTS; the client-side commands work with OpenSSH on Linux, macOS and Windows 10/11.

Prerequisites

  • A Linux or macOS workstation, or Windows with the built-in OpenSSH client.
  • The server's IP address (your_server_ip), the SSH port (22 unless you changed it) and the user you log in as (your_user).
  • For the server-side steps: a way to reach the server without SSH, such as the web-based console in your provider's control panel. A CubePath VPS running Ubuntu 24.04 is assumed in the examples.

Step 1 - Reading the error message

Run the connection once and read the last line carefully. Each common error points to a different layer:

ErrorMost likely causeGo to
Connection timed outServer down, wrong IP, or a firewall silently dropping port 22Step 2
No route to host / Network is unreachableRouting problem or a firewall rejecting the trafficStep 2
Connection refusedNothing listening on that port: sshd stopped or on another portStep 2, then Step 5
Connection closed by ... port 22 right after connectingfail2ban, MaxStartups or a banned IPStep 7
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!Server reinstalled or its host keys changedStep 4
Permission denied (publickey)Wrong key, wrong user, or bad permissions on the serverSteps 3 and 6
Too many authentication failuresYour agent offers too many keys before the right oneStep 3

Step 2 - Checking network reachability and the SSH port

First confirm that the server answers at all. Many servers drop ICMP, so a failed ping is a hint, not proof:

ping -c 4 your_server_ip

The decisive test is whether the TCP port accepts connections. Use nc (preinstalled on Ubuntu and macOS):

nc -vz -w 5 your_server_ip 22
Connection to your_server_ip 22 port [tcp/ssh] succeeded!

Interpret the result:

  • succeeded: the network and the port are fine; the problem is in SSH itself. Continue with Step 3.
  • Connection refused: the host is up, but nothing listens on that port. Check that you are using the right port, then Step 5.
  • timed out: packets are being dropped. Either the server is down, the IP is wrong, or a firewall (UFW on the server, a network firewall, or your office network) is blocking the port.

If you connect by hostname, make sure it resolves to the IP you expect:

dig +short your_domain

To see where packets stop on the way, use mtr (install it with sudo apt install mtr-tiny on Ubuntu or brew install mtr on macOS):

mtr -rwc 20 your_server_ip

Loss that starts at one hop and continues to the end points to that network. Loss only at the last hop with a working ping usually means the server is up and a firewall is filtering port 22.

Step 3 - Debugging the client with verbose output

When the port is open but login fails, run SSH in verbose mode. Add up to three v for more detail:

ssh -vvv your_user@your_server_ip

The lines worth looking for are:

debug1: Connecting to your_server_ip [your_server_ip] port 22.
debug1: Connection established.
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.6p1 Ubuntu-3ubuntu13
debug1: Authentications that can continue: publickey
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:...
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
your_user@your_server_ip: Permission denied (publickey).

This output tells you three useful things: the connection and key exchange worked, the server only accepts publickey (passwords are disabled), and the key your client offered was rejected. Either it is the wrong key, or the matching public key is not in the server user's ~/.ssh/authorized_keys.

Check which settings your client actually applies for this host, including anything from ~/.ssh/config:

ssh -G your_server_ip | grep -Ei '^(user|port|hostname|identityfile) '

If you have several keys loaded in your agent, the server may cut you off with Too many authentication failures before the right key is tried. Force a single key:

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 your_user@your_server_ip

On the client, the private key must be readable only by you, or SSH refuses to use it:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519

To test whether password login is possible (only if it is enabled on the server):

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no your_user@your_server_ip

Step 4 - Fixing host key verification errors

SSH stores each server's host key in ~/.ssh/known_hosts. If the server was reinstalled or rebuilt, its key changes and the client refuses to connect:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Only remove the old key when you know why it changed. If you did not reinstall the server, verify the fingerprint first from the server console:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

If it matches the fingerprint shown when you reconnect, remove the stale entry on your workstation:

ssh-keygen -R your_server_ip

Connect again and accept the new fingerprint after comparing it.

Step 5 - Checking the SSH service from the console

If the port is refused or filtered, log in through the web console and inspect the server directly. On Ubuntu 24.04, SSH is started through systemd socket activation, so check both the socket and the service:

sudo systemctl status ssh.socket ssh.service

Confirm what is listening and on which port:

sudo ss -tlnp 'sport = :22'
LISTEN 0      4096         0.0.0.0:22        0.0.0.0:*    users:(("systemd",pid=1,fd=58))
LISTEN 0      4096            [::]:22           [::]:*    users:(("systemd",pid=1,fd=59))

With socket activation the listener is owned by systemd, which is expected. If nothing listens, validate the configuration before restarting, since a syntax error prevents sshd from starting:

sudo sshd -t

No output means the configuration is valid. Then start it again:

sudo systemctl restart ssh.socket
sudo systemctl restart ssh.service

Review the recent log for the reason it failed:

sudo journalctl -u ssh -n 50 --no-pager

Next, check the firewall. With UFW active, SSH must be explicitly allowed:

sudo ufw status verbose

If the rule is missing, add it (use your custom port instead of OpenSSH if you changed it, for example sudo ufw allow 2222/tcp):

sudo ufw allow OpenSSH

Step 6 - Checking authentication on the server

The server log states exactly why an authentication was rejected. Watch it while you try to connect from your workstation:

sudo journalctl -u ssh -f

Typical messages and their meaning:

  • Invalid user admin from 203.0.113.10: the username does not exist on the server.
  • Authentication refused: bad ownership or modes for directory /home/your_user: permissions are too open.
  • Connection closed by authenticating user your_user ... [preauth]: the offered key did not match any entry in authorized_keys.

Print the effective server settings that matter for login. Ubuntu cloud images add files under /etc/ssh/sshd_config.d/, which can override the main file:

sudo sshd -T | grep -Ei '^(port|permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers|allowgroups) '
port 22
permitrootlogin without-password
pubkeyauthentication yes
passwordauthentication no

sshd is strict about permissions. The home directory must not be writable by others, and .ssh and authorized_keys must belong to the user:

sudo chown -R your_user:your_user /home/your_user/.ssh
sudo chmod 755 /home/your_user
sudo chmod 700 /home/your_user/.ssh
sudo chmod 600 /home/your_user/.ssh/authorized_keys

Finally, confirm the public key from your workstation is present. Print it locally with cat ~/.ssh/id_ed25519.pub and compare it with:

sudo cat /home/your_user/.ssh/authorized_keys

Each key must be on a single line. Keys pasted through a console often get broken across lines; fix that and try again.

Step 7 - Checking whether your IP is banned

If connections are accepted and then closed immediately, or suddenly time out after several failed attempts, your IP may have been banned by fail2ban, if it is installed. Check the SSH jail:

sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  `- Total failed:     14
`- Actions
   |- Currently banned: 1
   `- Banned IP list:   198.51.100.23

If your public IP is listed, unban it:

sudo fail2ban-client set sshd unbanip 198.51.100.23

Also review any AllowUsers or AllowGroups lines shown by sshd -T in the previous step: a user not listed there is rejected even with a valid key.

Conclusion

You checked SSH layer by layer: network reachability, the listening port, the client's keys and host key cache, the sshd service and its configuration, and bans. Working through the stages in this order narrows almost any SSH failure down to one cause in a few minutes. As next steps, consider setting up key-only authentication and fail2ban, and keep console access details at hand so a broken sshd_config never locks you out completely.