Short answer: ssh: connect to host … port 22: Connection timed out means your packets got no answer at all. Something dropped them on the way, they went to the wrong address, or the server is not running. That is different from Connection refused, where the server answers straight away with a no. Check, in this order, the IP address, whether the server is up, and whether a firewall drops port 22. On macOS the same failure reads Operation timed out, and PuTTY says Network error: Connection timed out.
# 1. Is it the right address? Copy the IP from your provider's panel,
# not from an old note or a DNS name that may still point elsewhere.
# 2. Is the server running? Open its console (VNC) in the panel and look
# for a login prompt.
# 3. Does anything answer on port 22?
nc -zv -w 5 203.0.113.10 22 # Linux, macOS
Test-NetConnection 203.0.113.10 -Port 22 # Windows PowerShell
# 4. Where exactly does ssh hang?
ssh -vvv root@203.0.113.10Skip ping as a test. Many servers and networks filter ICMP, so a failed ping proves nothing about SSH, and a working ping does not prove port 22 is open. nc and Test-NetConnection test the port itself: succeeded or TcpTestSucceeded : True means the network path is fine and the problem is in SSH itself. A timeout there confirms what ssh told you.
What is the difference between timed out and refused?
An SSH connection starts with a TCP handshake: your machine sends a SYN packet to port 22 and waits for a reply. What comes back decides the error.
- Connection refused: the server replied with a reset. The machine is up and reachable, but nothing listens on the port, or a firewall rejects it. The answer is fast and definite.
- Connection timed out: nothing came back. Your client resent the SYN a few times and gave up, after about two minutes on Linux by default. The packets were dropped silently, or they never reached a running server.
- No route to host: a router or firewall replied with an ICMP error. On Rocky Linux and CentOS Stream this is often firewalld, which rejects blocked ports by default instead of dropping them.
Browsers hit the same split on web ports and call it ERR_CONNECTION_TIMED_OUT and ERR_CONNECTION_REFUSED.
ssh -vvv shows where it stops. A plain timeout ends right after the connect attempt, before any SSH traffic:
debug1: Connecting to 203.0.113.10 [203.0.113.10] port 22.
debug1: connect to address 203.0.113.10 port 22: Connection timed out
ssh: connect to host 203.0.113.10 port 22: Connection timed outIf you see debug1: Connection established. and then it hangs, TCP got through and the problem is sshd itself. Jump to Connection timed out during banner exchange. To stop waiting two minutes per attempt while you test, add -o ConnectTimeout=10.
Where do the packets stop?
You do not have to guess between your network, the route and the server’s firewall. Watch port 22 on the server while you try to connect. You cannot use SSH for that, so open the provider’s console, find your own public IP (any “what is my IP” page, or curl -4 ifconfig.me on your computer) and run:
sudo apt install -y tcpdump # Rocky / CentOS Stream: sudo dnf install -y tcpdump
sudo tcpdump -ni any 'tcp port 22 and host 198.51.100.7'
# now run ssh from your computer and watch this window- Nothing appears: the packets never reach the server. Either the address is wrong, your own network blocks outbound port 22, a firewall in front of the server filters it, or the server has no working network. Check the network from the console with
ip -br addrandip route. - Lines with
Flags [S]arrive, but noFlags [S.]goes back: the server receives your SYN and stays silent. That is the host firewall dropping the port: ufw, firewalld or a hand-written nftables/iptables rule. tcpdump sees packets before the firewall does, so this pattern points straight at it. [S]in and[S.]out, but your client still times out: the reply is lost on the way back. This is rare, and usually a routing mistake on a server with several addresses, or a firewall on your own side.
Is it the right IP, and is the server running?
The boring causes come first, because they are the most common. A hostname can still resolve to an old server: compare dig +short server.example.com (or getent hosts server.example.com) with the IP in the panel, and connect to the raw IP while you test.
Then open the console and look at the screen. A stopped server, one still in its first boot, one sitting in emergency mode after a bad /etc/fstab edit, or one waiting on A start job is running… for its network all look the same from outside: silence. Log in on the console and check that the interface has its address and a default route:
ip -br addr # the public IP should be on an UP interface
ip route # there should be a "default via ..." line
ping -c 3 1.1.1.1 # can the server reach out at all?A netplan or /etc/network/interfaces edit with a typo is a classic way to end up here. The server boots fine and has no network.
Did a firewall start dropping port 22?
This is the most common cause on a server that worked yesterday. A firewall with a default “drop” policy produces exactly this error. The usual triggers:
- ufw was enabled before SSH was allowed. ufw drops incoming connections by default, and
ufw enablekeeps your current session alive because established connections are allowed. You only notice at the next login. - The SSH port was changed, but the firewall still allows only 22. sshd now listens on, say, 2222, and the firewall drops 2222. Connecting to 22 is refused because nothing listens there any more, and connecting to 2222 times out.
- A copied iptables or nftables ruleset with
policy dropand no rule for your port.
Fix it from the console, where the firewall cannot lock you out:
sudo ufw status verbose # is SSH in the list?
sudo ufw allow OpenSSH # port 22
sudo ufw allow 2222/tcp # or your custom port
sudo ufw status numberedsudo firewall-cmd --list-all # look at "services" and "ports"
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-port=2222/tcp # custom port
sudo firewall-cmd --reloadsudo nft list ruleset | less
sudo iptables -S INPUTThe ufw guide covers the right order: allow SSH first, then enable. If you are moving SSH to another port, do it in the order described in changing the SSH port without locking yourself out: open the new port in the firewall, then change sshd, then test.
Did fail2ban ban your IP?
If SSH works from your phone’s hotspot but not from home or the office, and fail2ban runs on the server, it has probably banned your address. A few mistyped passwords, a script retrying with a wrong key, or a colleague behind the same office IP are enough. Depending on the ban action, a banned address sees either a timeout (packets dropped) or Connection refused (packets rejected).
sudo fail2ban-client status sshd # "Banned IP list"
sudo fail2ban-client set sshd unbanip 198.51.100.7So that fail2ban never bans your own fixed IP again, add it to ignoreip in /etc/fail2ban/jail.local, then run sudo systemctl restart fail2ban:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 198.51.100.7Only add an address to ignoreip if it is really yours and fixed. The jail settings themselves are explained in securing SSH access.
Is your own network blocking outbound port 22?
Corporate networks, guest Wi-Fi, hotels and some schools block outgoing SSH. The server is fine, but your connection never leaves the building. Two quick tests:
nc -zv -w 5 github.com 22 # GitHub answers SSH on 22; a timeout here means your network blocks it
# or: switch to a phone hotspot and run the same ssh command againIf it works over the hotspot, the block is local. Use another network or a VPN. If you control the server, you can also make sshd listen on a second port that the network allows, 443 for example, if nothing else on the server uses it. Open that port in the firewall before you add it.
Is sshd on a different port, or is ssh trying IPv6?
On the server, check what sshd actually listens on:
sudo ss -tlnp
# look for 0.0.0.0:22 and [::]:22 (or your custom port).
# On Ubuntu 24.04 the port may be held by "systemd": ssh.socket listens
# and starts sshd on demand.If sshd is on another port, connect with ssh -p 2222 user@203.0.113.10. On Ubuntu 24.04, a Port change in sshd_config only takes effect after sudo systemctl daemon-reload and sudo systemctl restart ssh.socket, so the port you configured and the port that is open can differ. Checking open ports goes deeper into ss and lsof.
On the client side, a hostname with an AAAA record makes ssh try IPv6 first. If your network has broken IPv6, that attempt hangs until it times out. The verbose output shows it as Connecting to … [2001:db8::10] port 22. Force IPv4 to confirm:
ssh -4 user@server.example.comWhy does SSH work on the server but time out from outside?
If ssh localhost works on the server but connections from outside time out, sshd is fine and the block is between you and it. On a VPS that is almost always the host firewall or a filter in front of the server, so the tcpdump test above tells you which. On a machine at home or in an office, it is usually the router. Port 22 has to be forwarded to the machine’s LAN address, and that cannot work if your ISP puts you behind carrier-grade NAT, where your router has no public IPv4 address of its own.
What does “Connection timed out during banner exchange” mean?
Here TCP connected, so the firewall and the route are fine, but sshd never sent its greeting line (SSH-2.0-OpenSSH_…) in time. You see this wording when a connect timeout is set, as Ansible and many scripts do, or with ConnectTimeout in ~/.ssh/config. Without one, ssh simply hangs after Connection established. The usual reasons:
- The server is overloaded. It is out of memory and swapping hard, the CPU is pegged, or storage is stalled, so sshd cannot get scheduled to answer. Check from the console with
uptime,free -handtop, and look for OOM kills withsudo dmesg -T | grep -i killed. See processes killed when memory runs out and VPS high CPU usage. - Something else holds the port. A port forward or proxy accepts the connection but has nowhere to send it, or a different program listens on 22.
sudo ss -tlnpnames the process. - sshd is stuck.
sudo systemctl restart ssh(sshdon Rocky) from the console clears it. If it keeps coming back, look at the load first.
A full disk rarely blocks the banner itself, but it does break logins right after it, so run df -h while you are on the console. If the connection is cut off instead of hanging, that is a different error: Connection reset by peer.
All of these fixes assume a way in that does not depend on SSH. Every VMHeaven KVM plan has a VNC console in the panel, which reaches the server’s screen without SSH or a working network, so a firewall rule that locked you out takes a few minutes to undo, not a reinstall.
Frequently asked
What is the difference between 'Connection timed out' and 'Connection refused' in SSH?
Refused means the server answered at once with a TCP reset: the machine is reachable, but nothing listens on the port or a firewall rejects it. Timed out means nothing answered at all. The packets were dropped by a firewall, sent to the wrong IP, or the server is not running. Test the port with 'nc -zv -w 5 IP 22' or, on Windows, 'Test-NetConnection IP -Port 22'.
Can my ISP or network block SSH on port 22?
Yes. Corporate networks, guest Wi-Fi, hotels and some schools block outgoing port 22. Run 'nc -zv -w 5 github.com 22' or try the same ssh command over a phone hotspot. If it works there, the block is local. Use another network or a VPN, or let sshd listen on a second port the network allows.
How long after ordering a VPS will SSH work?
It depends on the provider. At VMHeaven, setup starts automatically once the payment is confirmed, and a Linux VPS is typically online within about a minute. If SSH still times out a few minutes later, open the VNC console in the panel to see whether the server has finished booting and has its network up.
Can fail2ban cause an SSH timeout?
Yes. When fail2ban bans your IP, its firewall rule either drops your packets, which looks like a timeout, or rejects them, which shows as Connection refused. Typically SSH then works from another network but not from yours. From the console, run 'sudo fail2ban-client status sshd' and 'sudo fail2ban-client set sshd unbanip YOUR_IP'.