When SSH says Connection refused, the connection attempt received an active rejection. That’s different from a timeout, where no response arrives, and from Permission denied, which means SSH reached the authentication stage but rejected your credentials.
The distinction helps narrow the search: a refusal usually points to the host, port, listener, or a firewall rule—not your SSH key.
Start by checking the destination and port
Confirm that the hostname or IP address is correct, especially if the server recently changed networks or received a new address. A successful ping can tell you that a host responds to ICMP, but it does not prove that SSH is available: ping and SSH use different protocols.
Next, test the TCP port from your client machine:
nc -vz example.com 22
On Windows, use PowerShell:
Test-NetConnection example.com -Port 22
These checks test the port independently of your SSH client. If the connection hangs rather than being rejected, you may be dealing with a timeout instead; that points to a different set of causes. This guide to SSH connection timeouts explains how to investigate that case.
Check whether the SSH server is running
If you can reach the machine another way—through a provider console, a local terminal, or a working alternate connection—check the SSH service there. You can’t check it remotely over the same port that’s refusing the connection.
The systemd service is commonly named ssh on Debian and Ubuntu, and sshd on RHEL-family distributions. If you’re unsure, search for it:
systemctl list-units --type=service | grep -i ssh
Then check its status, using the service name your system returned:
systemctl status ssh
# or
systemctl status sshd
If the service is installed but inactive, start it and enable it at boot:
sudo systemctl enable --now ssh
Use sshd instead of ssh if that’s the service name on your system. If the service is missing, the OpenSSH server may not be installed. On Debian or Ubuntu, install it with:
sudo apt install openssh-server
On RHEL, CentOS, or Fedora, use:
sudo dnf install openssh-server
Verify the port and listening address
A running service doesn’t guarantee it’s listening on the port or network interface your client is trying to reach. On the server, inspect listening TCP sockets:
ss -tlnp | grep ssh
Check both the port and the local address in the output. If SSH is listening on a custom port, connecting to the default port 22 will fail. Specify the actual port with -p:
ssh -p 2222 user@host
You can save a frequently used port in ~/.ssh/config:
Host myserver
HostName host
User user
Port 2222
The listening address matters too. A service bound only to 127.0.0.1 accepts connections from the machine itself, not from other machines. A ListenAddress setting in the SSH server configuration can also restrict which interfaces accept connections. For more on reading socket output and identifying listeners, see this practical overview of the Linux ss command.
The same issue can show up with virtual machines, containers, or servers with multiple network interfaces. A service may be running inside the guest or container but not reachable through the address or port your client is using. Check the relevant NAT, port-publishing, or forwarding layer as well as the SSH listener.
Check firewalls on the path
A firewall can actively reject a connection, producing “refused,” or silently drop it, which more often looks like a timeout. Check both the server’s firewall and any network-level firewall in front of it, such as a cloud security group.
For common Linux firewall front ends, inspect the current rules with:
# Debian / Ubuntu
sudo ufw status
# RHEL / CentOS / Fedora
sudo firewall-cmd --list-all
If SSH uses port 22 and the server’s UFW rules don’t allow it, add an allow rule:
sudo ufw allow 22/tcp
For firewalld, allow the SSH service permanently and reload the rules:
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
If SSH uses a custom port, make sure the firewall allows that port instead. Only open access where it’s needed; a rule on the server won’t help if a cloud firewall or network device still blocks the connection.
A special case: a new Raspberry Pi
Raspberry Pi OS has SSH disabled by default. For a headless setup, the Raspberry Pi Imager can enable SSH during imaging. You can also enable it from Raspberry Pi Configuration or with sudo raspi-config.
For headless setup after imaging, an empty file named ssh in the boot partition can enable the service on first boot. On current Raspberry Pi OS releases, enabling SSH alone doesn’t create a login account. Create a user during imaging, or follow the current OS’s account setup process as well.
Keep the troubleshooting order simple
Work from the outside in: confirm the destination, test the TCP port, check that the server process is running, verify its port and bind address, then inspect firewalls and forwarding rules. If you reach a password prompt or see Permission denied (publickey), the TCP connection and SSH service are working; investigate authentication instead.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)