What "Connection refused" means
When ssh prints ssh: connect to host 203.0.113.10 port 22: Connection refused, your packets reached a machine at that address and something answered with a firm "no". Either nothing was listening on port 22, so the kernel sent back a TCP reset, or a firewall rule rejected the connection with an error reply. Your key and password have not been checked yet, because the SSH handshake never started.
So the network path is mostly fine; the problem is on the server or in the address and port you are using.
Quick-fix checklist
- Confirm the address and port:
ssh -v user@203.0.113.10and read theConnecting to ... port 22line. - Test the port without SSH:
nc -zv 203.0.113.10 22. - Open the provider's web or VNC console and log in there.
- Check the daemon:
systemctl status ssh(Ubuntu, Debian) orsystemctl status sshd(AlmaLinux, Rocky, RHEL). - See what is listening:
sudo ss -tlnp | grep ssh. - Validate the config before restarting:
sudo sshd -t. - Check the firewall and fail2ban for a rule or ban on your IP.
Refused vs timed out vs permission denied
These three errors happen at different stages, so they point to different fixes.
| Error | What happened | Look at |
|---|---|---|
Connection refused | Host replied; port closed or connection rejected | sshd status, listening port, firewall REJECT rules, fail2ban |
Connection timed out | No reply at all | Firewall DROP rules, provider firewall, wrong or dead IP, server powered off |
Permission denied (publickey) | Connected and negotiated; authentication failed | Username, key file, authorized_keys permissions, PasswordAuthentication |
If you see Permission denied, stop debugging the network: port 22 is open and sshd is running.
Diagnose from your own machine first
Run the client in verbose mode. Each extra v adds detail, up to three:
ssh -vvv root@203.0.113.10
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
Check that the IP and port are the ones you expect. A Port or HostName line in ~/.ssh/config can silently change both. Then test the port directly:
nc -zv 203.0.113.10 22
nc -zv 203.0.113.10 2222
If a different port succeeds, sshd was moved and you only need ssh -p 2222.
Getting in when SSH is dead
Most fixes below need a shell on the server. When SSH is the thing that is broken, use the provider's out-of-band console: a web, VNC or serial console in the control panel that works like a keyboard and screen plugged into the machine. It does not depend on sshd or the network firewall, so you can log in as root (or a user with sudo) with the account password. If you only ever used keys and never set a password, many panels let you reset the root password, or you can boot a rescue image.
Cause 1: sshd is not running
A failed upgrade, a bad config edit or a disabled unit leaves nothing listening on port 22.
systemctl status ssh # Ubuntu, Debian
systemctl status sshd # AlmaLinux, Rocky, RHEL
systemctl status ssh.socket # Ubuntu 22.10 and later
sudo journalctl -u ssh -n 50 --no-pager # -u sshd on RHEL family
If the log shows a config error, test the file. sshd -t checks the configuration and host keys and prints the line it does not like; sshd -T prints the effective settings.
sudo sshd -t
sudo systemctl enable --now ssh # Ubuntu 22.04, Debian
sudo systemctl enable --now ssh.socket # Ubuntu 22.10 and later
sudo systemctl enable --now sshd # AlmaLinux, Rocky, RHEL
Run sshd -t before every restart: a config typo that stops sshd starting is the usual way people lock themselves out.
Cause 2: sshd listens on another port or address
Check what is actually listening. In ss -tlnp, -t means TCP, -l listening sockets, -n numeric ports and -p the owning process:
sudo ss -tlnp | grep -E 'ssh|:22'
LISTEN 0 128 0.0.0.0:2222 0.0.0.0:* users:(("sshd",pid=812,fd=3))
Here sshd is on 2222, not 22. Also look for 127.0.0.1:22, which means a ListenAddress line limits sshd to localhost. Compare with the config:
sudo sshd -T | grep -Ei '^(port|listenaddress)'
Ubuntu 22.10 and later: ssh.socket
From Ubuntu 22.10, OpenSSH is started by systemd socket activation: ssh.socket owns the listening port and starts sshd when a connection arrives. Two consequences matter here.
systemctl status sshcan show the service as inactive while SSH works fine. Checksystemctl status ssh.socketas well.- On Ubuntu 24.04, changing
Portinsshd_configand restartingssh.servicedoes nothing; the socket keeps listening on the old port. The socket settings are generated fromsshd_config, so you must regenerate them.
sudo sshd -t
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -tlnp | grep ssh
On 22.10 to 23.10, the port is set on the socket, not read from sshd_config. Upgrades moved any custom port into /etc/systemd/system/ssh.socket.d/addresses.conf, so check that file. To change it on those releases, put an empty ListenStream= line followed by ListenStream=2222 under [Socket] in a drop-in in that directory (the empty line clears port 22 instead of adding to it), then run the daemon-reload and restart ssh.socket commands above. Ubuntu 22.04 and earlier, Debian and AlmaLinux run sshd as a normal service, where editing Port and restarting ssh or sshd is enough. On AlmaLinux, Rocky and RHEL, SELinux only lets sshd bind to permitted ports, so allow a new port first with sudo semanage port -a -t ssh_port_t -p tcp 2222, or sshd fails to start. Whatever the release, confirm with ss -tlnp and a second SSH session before closing the first.
Cause 3: a firewall rejects the connection
Firewalls either drop packets silently, which gives a timeout, or reject them with a reply, which gives "refused". In iptables, the REJECT target replies with ICMP port-unreachable by default; with ufw, reject tells the sender while deny ignores the traffic.
# ufw (Ubuntu, Debian)
sudo ufw status verbose
sudo ufw allow 22/tcp # or your custom port
# firewalld (AlmaLinux, Rocky)
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-port=2222/tcp # custom port; --add-service=ssh for 22
sudo firewall-cmd --reload
# raw rules
sudo iptables -L INPUT -n --line-numbers
sudo nft list ruleset
If you moved SSH to a new port, open that port in the server firewall and in any firewall your provider runs in front of the server before you restart sshd. firewalld rejects packets that match no rule with an ICMP "prohibited" reply, which the client usually reports as "No route to host" rather than "Connection refused"; a plain "refused" points more to a stopped sshd, a closed port or an explicit port-unreachable reject rule.
Cause 4: fail2ban banned your IP
After several failed logins, fail2ban adds a rule for your address. Its stock iptables action uses REJECT --reject-with icmp-port-unreachable (the nftables action also rejects), so a ban usually looks exactly like a closed port, while the server still works from other networks. A quick test is to try from mobile data.
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 198.51.100.7
Add your office or home IP to ignoreip in /etc/fail2ban/jail.local if it changes rarely. Also note ufw's limit rule denies an address that opens six or more connections in 30 seconds, which scripts and some deploy tools can trigger.
Cause 5: wrong IP or stale DNS
If you connect by hostname, the A or AAAA record may still point to an old server, or your client may prefer IPv6 where sshd only listens on IPv4. Compare:
dig +short server.example.com A
dig +short server.example.com AAAA
ssh -4 root@server.example.com
An IP that now belongs to a different machine with no SSH service also returns "refused". Copy the address from your provider's panel rather than from old notes.
Cause 6: the server is rebooting or out of memory
During a reboot there is a short window when the network is up but sshd has not started, so connections are refused; wait a minute and retry. On a small VPS, the kernel's OOM killer can also end sshd when memory runs out. From the console, check:
sudo journalctl -k | grep -i -E 'out of memory|killed process'
free -h
sudo systemctl restart ssh # sshd on AlmaLinux, Rocky, RHEL
If it keeps happening, add swap, cap the memory-hungry service, or move to a plan with more RAM.
If you do not own the server
With only SSH details, you can check the address, port and username, and try another network to rule out a ban. Everything else needs root access, so send the owner your full ssh -v output, your public IP and the time you tried.
How this applies on Bigdomainhost
On a Bigdomainhost KVM VPS you have full root access, a dedicated IPv4 address and an IPv6 /64. The server firewall policy is deny-inbound except SSH on port 22, with per-instance inbound rules you edit in the control panel without SSH; if you move sshd to another port, add a rule for it there first. The networking and firewall docs cover the defaults.
If SSH is down, open the out-of-band console in the control panel, which keeps working after a firewall mistake or a broken fstab. If you picked an Ubuntu image, check which release you run with lsb_release -a before following the ssh.socket steps above. The same diagnosis applies to dedicated servers and to a VPS where you have installed cPanel. If you are stuck, call or WhatsApp support 24x7 on +91 75994 50220 or email support@bigdomainhost.com.
Sources (checked )
- Ubuntu Manpages: ssh - OpenSSH remote login client
- OpenBSD manual pages: sshd(8)
- Ubuntu Discourse: SSHd now uses socket-based activation (Ubuntu 22.10 and later)
- Launchpad (Ubuntu): Bug #2069041: Changing Port in sshd_config requires calling systemctl daemon-reload
- Ubuntu Manpages: ufw - program for managing a netfilter firewall
- man7.org: iptables-extensions(8)
- fail2ban (GitHub): action.d/iptables.conf: default blocktype
- firewalld.org: Zone options: target and default reject