Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 9 min read Last reviewed Jul 2026

Linux Error: 'ssh: connect to host ... port 22: Connection timed out' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix 'ssh: connect to host port 22: Connection timed out': diagnose firewall/security-group drops, a down host, sshd not listening, and routing with nc, ss and ssh -v.

  • #linux
  • #troubleshooting
  • #ssh
  • #networking
Free toolkit

Stuck on this Linux Admins error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

What this error means

You try to SSH to a server and, after a long pause, the connection gives up:

ssh: connect to host 10.0.0.5 port 22: Connection timed out

The tell-tale sign is the delay — often 15 to 130 seconds. SSH sent TCP SYN packets to port 22 and never got a reply, so the kernel eventually gave up. That silent drop points at the network path or the host being down, not at the SSH protocol itself. Something (a firewall, a cloud security group, a missing route, or a powered-off host) is swallowing the packets.

This is distinct from two errors people confuse it with:

  • Connection refused — an instant rejection (TCP RST): the host is up and reachable, but nothing is listening on port 22. See SSH connection refused.
  • Host key verification failed — the TCP connection succeeded; SSH connected but distrusts the server’s key. See Host key verification failed.

A timeout means you never even reached a listening socket.

How it presents

  • ssh hangs for many seconds, then prints connect to host <ip> port 22: Connection timed out.
  • ssh -v stalls at Connecting to <host> port 22 with no Connection established.
  • nc -vz -w 5 <host> 22 times out rather than succeeding or refusing.
  • SSH to other hosts works; only this one hangs — pointing at a per-host firewall/security-group rule.
  • The failure appeared right after a firewall change, an instance restart, or an IP change.

Tracing the connection

Work outward from your client toward the server.

  1. Confirm basic reachability and time the failure (long hang = dropped, not refused):

    ping -c3 10.0.0.5
    time nc -vz -w 5 10.0.0.5 22
  2. Get SSH’s own view of where it stalls:

    ssh -v deploy@10.0.0.5

    Stalling at Connecting to ... port 22 confirms the TCP handshake never completes.

  3. Check the path for where packets die:

    traceroute -T -p 22 10.0.0.5      # TCP traceroute to port 22
    mtr -rw 10.0.0.5
  4. Make sure you are targeting the right address:

    getent hosts server.example.internal
    ip route get 10.0.0.5
  5. On the server (via console / cloud serial console if SSH is dead), confirm sshd is listening and the firewall allows it:

    sudo ss -tlnp | grep ':22'            # sshd bound to 0.0.0.0:22 (or the intended IP)
    sudo systemctl status ssh sshd
    sudo ufw status verbose               # Ubuntu/Debian
    sudo firewall-cmd --list-all          # RHEL/Rocky
    sudo iptables -S | grep -iE 'drop|22'

Network path causes

  1. Firewall or cloud security group dropping the SYN. An AWS security group / GCP firewall / Azure NSG with no inbound rule for port 22 (or from your source IP), or an OS-level iptables -j DROP / ufw deny. This is the single most common cause.
  2. The host is down or unreachable. Powered off, crashed, or still booting — SYNs go unanswered.
  3. Wrong IP or hostname. You are timing out against a stale, reassigned, or private address that is not reachable from where you are.
  4. sshd not listening on the expected port/interface (bound to a different port, or to 127.0.0.1 only). This can present as a timeout if a firewall also silently drops, though a purely-not-listening host usually refuses.
  5. Routing / NAT problem. Packets leave but never reach the host, or replies cannot return (asymmetric routing, missing route, black-holing NAT/load balancer).

Remediation steps

  1. Open port 22 in the cloud security group first — this is the most common fix. Add an inbound TCP/22 rule scoped to your source CIDR in the AWS security group / GCP firewall / Azure NSG. Then, on the OS firewall:

    sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp          # Ubuntu/Debian
    sudo firewall-cmd --add-service=ssh --permanent && sudo firewall-cmd --reload   # RHEL/Rocky
  2. Bring the host up / confirm it booted. For cloud instances, check the console output and instance state; restart it if it is stopped or hung.

  3. Correct the target host/port. If the server listens on a non-standard port, tell SSH:

    ssh -p 2222 deploy@10.0.0.5

    And verify you are using the current, reachable IP (public vs private).

  4. Make sshd listen where clients can reach it. If ss -tlnp shows sshd on the wrong port or only on loopback, fix /etc/ssh/sshd_config:

    Port 22
    ListenAddress 0.0.0.0

    Then validate and reload:

    sudo sshd -t
    sudo systemctl reload ssh    # or 'sshd' on RHEL
    sudo ss -tlnp | grep ':22'
  5. Allow the user if AllowUsers/AllowGroups excludes them. A user missing from AllowUsers is usually refused after connect rather than timed out, but confirm the directive while you are in sshd_config:

    AllowUsers deploy admin
  6. Repair routing if ip route get shows the wrong path or no route:

    ip route get 10.0.0.5
    sudo ip route add 10.0.0.0/24 via 10.0.0.1 dev ens3

    Warning: Editing firewall or routing rules over SSH can cut off your own session. Keep the cloud serial/console open, or stage a timed iptables-restore auto-revert before applying changes on a remote host.

Keeping the path healthy

  • The delay is the diagnostic. A long hang = dropped packets (firewall/security group/down host); an instant failure = Connection refused (host up, nothing on port 22). They lead to different fixes.
  • Security groups vs OS firewall are two separate layers. Opening ufw does nothing if the cloud security group still drops port 22, and vice versa. Check both.
  • nc/ping can themselves be filtered. A blocked ping does not prove the host is down; trust the TCP/22 probe (nc -vz, ssh -v) over ICMP.
  • This is not Host key verification failed. If SSH gets far enough to complain about a host key, the TCP connection already succeeded — that is a different problem, covered in its own guide.
  • Bound --connect-timeout/-w on your probes so you are not waiting on the default multi-minute TCP timeout while testing.

Want faster Linux incident response? Use DevOps AI Toolkit to turn production errors into clear diagnostics, remediation steps, and reusable runbooks.

Free download · 368-page PDF

Fixed it? Get 500 Linux Admins & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.