TL;DR:
- SSH connection refused means the server answered, but nothing accepted a connection on the SSH port, usually 22: SSH is stopped, listens on another port, or a firewall rule or Fail2ban ban rejected you.
Connection timed out(Operation timed outon macOS) means no reply came back: a wrong IP address, a server that is off or booting, or a firewall that drops packets, such as UFW's default deny.- On Ubuntu 24.04 and 26.04,
ssh.socketholds the SSH port. After a port change, runsudo systemctl daemon-reloadandsudo systemctl restart ssh.socket. - Run
sudo sshd -tbefore every restart. A configuration error first resets connections, then systemd stops the socket and every attempt is refused. - A UFW
limitrule refuses the 6th connection within 30 seconds. Fail2ban's default SSH jail bans an address for 10 minutes after 5 failures in 10 minutes. - After a Rebuild, compare the new host key fingerprint in the console, then remove the old key on your computer with
ssh-keygen -R YOUR_SERVER_IP.
Applies to: Ubuntu 24.04 LTS and 26.04 LTS (OpenSSH 9.6p1 and 10.2p1) · Debian 12 and 13 (SSH service steps) · UFW 0.36.2 · Fail2ban 1.0.2 and 1.1.0 · checked November 2026
SSH connection refused is the OpenSSH client error ssh: connect to host YOUR_SERVER_IP port 22: Connection refused, printed when the server rejects the TCP connection before the SSH handshake: the address answers, but nothing accepts a connection on the SSH port, or a firewall rule rejects it. This tutorial separates it from timed out and permission denied, then checks the address and port, the SSH service, the configuration, UFW, Fail2ban, a server that is still booting, and the host key warning after a Rebuild. The commands are for Ubuntu and Debian.
Why is my SSH not connecting? Refused, timed out or denied
The last words of the error tell you where to look.
| Error on your computer | What it means | Where to look |
|---|---|---|
Connection refused | The address answered, but nothing accepted the connection on that port, or a firewall rule rejected it | Steps 1 to 6 |
Connection timed out (Operation timed out on macOS) | No reply came back | Steps 1, 5 and 7 |
No route to host | The network found no host at that address, or a firewall rejected the connection with an ICMP prohibited reply, as firewalld does by default | Steps 1, 5 and 7 |
Network is unreachable | Your computer has no route to that network, such as an IPv6 address on a connection without IPv6 | Step 1 |
kex_exchange_identification: read: Connection reset by peer | The port accepted the connection and closed it before login: the SSH service failed to start, or OpenSSH 9.8 and later, as on Ubuntu 26.04 and Debian 13, refuses your address for a while after failed logins | Steps 4 and 6 |
Permission denied (publickey) | SSH runs and rejected your user or key | SSH key troubleshooting |
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! | The server's host key differs from the saved one | After a Rebuild |
Prerequisites
- The server's IP address and its SSH port. The default port is 22.
- A non-root user with sudo privileges and SSH key login. How to Generate an SSH Key on Windows, macOS, and Linux creates the key and the sudo user.
- A way to run commands on the server while SSH is down. Arct Cloud's VNC Console gives direct browser-based access to the server when SSH is not working or you are locked out. It is available on the server detail page while the server is Running.
Step 1 runs on your computer. Steps 2 to 6 run on the server, in the console or in an SSH session that still works, as the sudo user. Replace values written in capitals, such as YOUR_SERVER_IP and YOUR_IP, with your own. The examples use 203.0.113.10 as the server and 198.51.100.20 as your address.
Step 1: Check the address and port you connect to
A typo in the IP address or an old Port line in ~/.ssh/config sends ssh to the wrong place. Print the settings ssh uses for a host or an alias such as web1:
ssh -G web1 | grep -E '^(user|hostname|port) '
The output looks similar to this:
user deploy
hostname 203.0.113.10
port 2222
If the port is wrong, fix the Port line in ~/.ssh/config or pass -p. Verbose mode shows the address and port ssh tries:
ssh -v -p 22 YOUR_USER@YOUR_SERVER_IP
Among the debug lines, the last ones look similar to this:
debug1: Connecting to 203.0.113.10 [203.0.113.10] port 22.
debug1: connect to address 203.0.113.10 port 22: Connection refused
ssh: connect to host 203.0.113.10 port 22: Connection refused
To test the port without SSH, run nc -zv -w 5 YOUR_SERVER_IP 22 on macOS or Linux, or Test-NetConnection YOUR_SERVER_IP -Port 22 in PowerShell on Windows, which reports the result in its TcpTestSucceeded line. When no reply comes back, a Linux client waits about 2 minutes before it prints Connection timed out; -o ConnectTimeout=10 stops after 10 seconds. PuTTY prints Network error: Connection refused or Network error: Connection timed out.
If nc -zv -w 5 github.com 22 fails too, the block is on your own network or computer. GitHub's documentation notes that some firewalls refuse SSH connections entirely.
Step 2: Check that the SSH server is running
On Ubuntu 24.04 and 26.04, ssh.socket listens on the SSH port and starts ssh.service at the first connection. Debian 12 and 13 run ssh.service without the socket, so on Debian go to systemctl status ssh below. On Ubuntu, check the socket:
systemctl status ssh.socket --no-pager
The output looks similar to this:
● ssh.socket - OpenBSD Secure Shell server socket
Loaded: loaded (/usr/lib/systemd/system/ssh.socket; enabled; preset: enabled)
Active: active (listening) since Fri 2026-11-06 17:41:43 UTC; 3ms ago
...
Triggers: ● ssh.service
Listen: 0.0.0.0:22 (Stream)
[::]:22 (Stream)
On Ubuntu, Active: inactive (dead) means nothing listens, so every attempt is refused. Start the socket and enable it at boot:
sudo systemctl enable --now ssh.socket
Active: failed (Result: service-start-limit-hit) means SSH failed to start, usually because of a configuration error. Go to Step 4 before you start the socket again.
After a reboot, systemctl status ssh shows Active: inactive (dead) next to TriggeredBy: ● ssh.socket until the first connection starts the service.
On Debian, and on Ubuntu servers with socket activation turned off, check systemctl status ssh and start it with sudo systemctl enable --now ssh. Then check what listens on the SSH port:
sudo ss -tlnp 'sport = :22'
The output looks similar to this:
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("systemd",pid=1,fd=60))
LISTEN 0 4096 [::]:22 [::]:* users:(("systemd",pid=1,fd=61))
If only the header line prints, nothing listens on port 22. On Ubuntu, systemd holds the port until the first login starts sshd. Replace 22 with your port if you changed it.
Install and enable SSH on an Ubuntu server
On Ubuntu and Debian, if systemctl status ssh prints Unit ssh.service could not be found., or the socket check prints Unit ssh.socket could not be found., the SSH server is not installed:
sudo apt update
sudo apt install openssh-server
The package enables and starts ssh.socket on Ubuntu and ssh.service on Debian.
Step 3: Fix an SSH port change that is not working
Since Ubuntu 22.10, OpenSSH starts through systemd socket activation, and from Ubuntu 24.04 a systemd generator reads Port and ListenAddress from the SSH configuration, as Ubuntu's announcement describes. The generator runs at systemctl daemon-reload, so a new Port line followed by sudo systemctl restart ssh leaves SSH on port 22. Compare the configured port with the port the socket listens on:
sudo sshd -T | grep '^port '
systemctl status ssh.socket --no-pager | grep -A1 'Listen:'
The output looks similar to this:
port 2222
Listen: 0.0.0.0:22 (Stream)
[::]:22 (Stream)
The configuration says 2222 while the socket listens on 22, so ssh -p 2222 is refused. If UFW is active, allow the new port first:
sudo ufw allow 2222/tcp
Regenerate the socket from the configuration and restart it, the two commands Ubuntu's /etc/ssh/sshd_config also lists above #Port 22:
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
systemctl status ssh.socket --no-pager now shows a Drop-In line for /run/systemd/generator/ssh.socket.d/addresses.conf and the new port:
Listen: 0.0.0.0:2222 (Stream)
[::]:2222 (Stream)
Port 22 now refuses connections. Keep your current session open and log in from a second terminal with ssh -p 2222 YOUR_USER@YOUR_SERVER_IP. If the new port does not answer, go back from the session you kept open: delete the Port 2222 line and run the two commands again. After the login on port 2222 works, remove the port 22 rule with sudo ufw delete allow OpenSSH. On Debian 12 and 13, sudo systemctl restart ssh applies a port change.
Step 4: Test the SSH configuration for errors
sshd -t is OpenSSH's test mode: it checks the configuration file and the host keys without restarting anything. Ubuntu's ssh.service runs the same test before it starts, so an error keeps SSH down.
sudo sshd -t
No output means the configuration is valid. A typo prints the file and the line:
/etc/ssh/sshd_config.d/10-local.conf: line 1: Bad configuration option: PasswordAuthentcation
/etc/ssh/sshd_config.d/10-local.conf: terminating, 1 bad configuration options
Ubuntu reads /etc/ssh/sshd_config.d/ before the rest of /etc/ssh/sshd_config, and for most options the first value wins. Fix the line with sudo nano and the file name, then save with Ctrl+O and exit with Ctrl+X.
If sudo sshd -t prints only Missing privilege separation directory: /run/sshd, the configuration parsed without errors. systemd removes that folder when the SSH service stops, and on Ubuntu 24.04 it is also missing after a reboot until the first connection starts the service. Create it and test again:
sudo install -d -m 0755 /run/sshd
sudo sshd -t
From your computer, a broken configuration first shows kex_exchange_identification: read: Connection reset by peer. After a few failed starts, systemd stops the socket too, and sudo journalctl -u ssh.socket -n 1 --no-pager shows:
Nov 06 17:41:55 web1 systemd[1]: ssh.socket: Failed with result 'service-start-limit-hit'.
From then on every attempt is refused. Clear the failed state and start the socket again:
sudo systemctl reset-failed ssh ssh.socket
sudo systemctl restart ssh.socket
Without reset-failed, a restart a few seconds after the failures hits the same limit. On Debian, run sudo systemctl reset-failed ssh and sudo systemctl restart ssh.
Step 5: Check the firewall rules
The Uncomplicated Firewall (UFW) decides whether a blocked connection is refused or times out. Check it:
sudo ufw status
Status: inactive means UFW is not the cause. With UFW active, the rule for your SSH port sets the error:
| UFW rule for the SSH port | What ssh prints |
|---|---|
| None, with the default deny incoming | Connection timed out |
deny | Connection timed out |
reject | Connection refused |
limit, from the 6th connection within 30 seconds | Connection refused |
allow | The SSH login goes through |
UFW applies the first rule that matches, so an allow rule added after a reject or deny rule changes nothing. Delete the blocking rule first: sudo ufw delete reject 22/tcp or sudo ufw delete deny 22/tcp removes the IPv4 and IPv6 rules together. A delete by number from sudo ufw status numbered removes one rule, so delete the (v6) copy as well. Then allow SSH on port 22:
sudo ufw allow OpenSSH
For another port, run sudo ufw allow 2222/tcp instead.
A limit rule rejects an address that opens 6 or more connections within 30 seconds, so a script that runs ssh or scp in a loop gets Connection refused from the 6th run. The next connection works after 30 seconds without attempts. To exempt your own address and keep the limit for everyone else, insert an allow rule above it:
sudo ufw insert 1 allow from YOUR_IP to any port 22 proto tcp
YOUR_IP is your public address, and UFW prints Rule inserted.
How to Set Up a UFW Firewall on Ubuntu 26.04 covers the rules in full. If UFW is inactive and connections still fail, sudo nft list ruleset prints every firewall rule on the server, including rules that other tools added.
Step 6: Check for a Fail2ban ban and unban your IP
Fail2ban bans addresses with repeated failed logins by adding a firewall rule. Ubuntu's package turns on the SSH jail, and the defaults in jail.conf ban an address for 10 minutes after 5 failures in 10 minutes. With Ubuntu's default nftables action and with the UFW action, the ban rejects packets, so ssh prints Connection refused. Without Fail2ban, go to the OpenSSH penalty at the end of this step. Check the jail:
sudo fail2ban-client status sshd
The output looks similar to this:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 198.51.100.20
Unban your address:
sudo fail2ban-client set sshd unbanip YOUR_IP
The command prints 1, the number of addresses unbanned. Connect again from your computer with ssh YOUR_USER@YOUR_SERVER_IP. sudo fail2ban-client banned lists the banned addresses in every jail. If you cannot tell which one is yours, sudo fail2ban-client unban --all clears every ban, including the bans on other addresses. To keep your own address off the list, add it to ignoreip as How to Install and Configure Fail2ban shows.
Wait for an OpenSSH penalty to end
OpenSSH 9.8 and later, as on Ubuntu 26.04 and Debian 13, refuses an address for a while after failed logins, up to 10 minutes by default (PerSourcePenalties in the sshd_config manual). The client prints kex_exchange_identification: read: Connection reset by peer, and sudo journalctl -u ssh -g penalty --no-pager shows lines that end in penalty: failed authentication. In testing, 4 failed key logins gave a 19-second penalty. Fix the key or user name that failed, then connect again after the penalty ends.
Step 7: Wait for the server to finish booting
After a Restart or a Rebuild, attempts time out or are refused until the server's network and the SSH socket are up. Check that the dashboard shows the server as Running, then wait for the SSH port from your computer:
until nc -z -w 5 YOUR_SERVER_IP 22; do sleep 5; done
If SSH listens on another port, replace 22 with that port. On Linux, the loop ends with this line when the port opens:
Connection to 203.0.113.10 22 port [tcp/ssh] succeeded!
Connect with ssh YOUR_USER@YOUR_SERVER_IP. If the port never opens, work through Steps 2 to 6 in the console. A configuration error made before the reboot keeps SSH down after it, because Ubuntu runs sshd -t before it starts the service.
After a Rebuild: fix the host key changed warning
A Rebuild reinstalls the operating system and erases the disk, so the server gets new SSH host keys. Your computer still has the old key in ~/.ssh/known_hosts and stops before login:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
...
The fingerprint for the ED25519 key sent by the remote host is
SHA256:GOggsWv2WIU+IhNdTIM1bhyucN3nf+t64p2NTdyOXR0.
...
Host key verification failed.
The same warning appears when someone intercepts the connection, so confirm that the Rebuild was yours. Print the new fingerprint in the console and compare it:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:GOggsWv2WIU+IhNdTIM1bhyucN3nf+t64p2NTdyOXR0 root@web1 (ED25519)
When the fingerprints match, remove the old key on your computer:
ssh-keygen -R YOUR_SERVER_IP
The output ends with:
/home/alex/.ssh/known_hosts updated.
Original contents retained as /home/alex/.ssh/known_hosts.old
For a port other than 22, run ssh-keygen -R '[YOUR_SERVER_IP]:2222'. The next connection asks you to confirm the new key; type yes to save it. Users, keys and firewall rules you added before the Rebuild were on the erased disk, so set up the sudo user and its key again, as How to Generate an SSH Key on Windows, macOS, and Linux shows, before ssh YOUR_USER@YOUR_SERVER_IP works.
Prevent SSH connection refused errors
- Keep a second SSH session open while you change SSH, UFW or Fail2ban settings, and test each change from a new terminal.
- Add your own address to Fail2ban's
ignoreip, and keep each server'sHostName,UserandPortcurrent in~/.ssh/config.
FAQ
What does SSH connection refused on port 22 mean?
It means your computer reached the server, but nothing accepted a connection on port 22. SSH is stopped, listens on another port, or a firewall rule or a Fail2ban ban rejected the attempt.
Why is my SSH connection refused after changing the port?
On Ubuntu 24.04 and 26.04, ssh.socket keeps the old port until you run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket. Restarting the ssh service alone leaves SSH on port 22. Allow the new port in UFW before you switch.
What is the difference between connection refused and connection timed out?
Refused means the server answered with a rejection, so the address works and the port is closed or blocked. Timed out means no answer came back: a wrong IP, a server that is off or booting, or a firewall that drops packets, such as UFW's default deny.
Can a firewall cause SSH connection refused?
Yes. A UFW reject rule, a UFW limit rule from the 6th connection within 30 seconds, and a Fail2ban ban all send a rejection, which ssh prints as Connection refused. UFW's default deny and its deny rules drop packets, so those connections time out instead.
How do I unban my IP address from Fail2ban?
Run sudo fail2ban-client set sshd unbanip followed by your address, from the server console or from another network. sudo fail2ban-client banned lists the banned addresses, and sudo fail2ban-client unban --all clears every ban.
How do I get into my server if SSH is not working?
Use a console that does not depend on SSH. On Arct Cloud, the VNC Console gives direct browser-based access to the server when SSH is not working. It is available on the server detail page while the server is Running.
Why does SSH say connection refused right after a reboot?
The server is still starting, and the port refuses connections until the SSH socket listens. If the refusal continues, a configuration error may stop SSH from starting: run sudo sshd -t and sudo journalctl -u ssh in the console.
Next steps
- SSH tunnels and port forwarding, to reach private dashboards over SSH
- SSH connection troubleshooting in the docs
- OpenSSH server in the Ubuntu Server documentation
Arct Cloud Linux images deploy in under 30 seconds on every Linux VPS plan. Compare plans.
This work is licensed under CC BY-NC-SA 4.0.