All tutorials
15 min read

How to Fix SSH Connection Refused on a Linux Server

Fix SSH connection refused on a Linux server and get back in: check that SSH is running, that your firewall lets it through and that you are not banned.

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 out on 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.socket holds the SSH port. After a port change, run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket.
  • Run sudo sshd -t before every restart. A configuration error first resets connections, then systemd stops the socket and every attempt is refused.
  • A UFW limit rule 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 computerWhat it meansWhere to look
Connection refusedThe address answered, but nothing accepted the connection on that port, or a firewall rule rejected itSteps 1 to 6
Connection timed out (Operation timed out on macOS)No reply came backSteps 1, 5 and 7
No route to hostThe network found no host at that address, or a firewall rejected the connection with an ICMP prohibited reply, as firewalld does by defaultSteps 1, 5 and 7
Network is unreachableYour computer has no route to that network, such as an IPv6 address on a connection without IPv6Step 1
kex_exchange_identification: read: Connection reset by peerThe 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 loginsSteps 4 and 6
Permission denied (publickey)SSH runs and rejected your user or keySSH key troubleshooting
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!The server's host key differs from the saved oneAfter 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 portWhat ssh prints
None, with the default deny incomingConnection timed out
denyConnection timed out
rejectConnection refused
limit, from the 6th connection within 30 secondsConnection refused
allowThe 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's HostName, User and Port current 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

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.