Error message
Connection refused
You reached the machine, but nothing was listening on that port — or a firewall said no.
Quick diagnosis
Start here. This one command usually tells you which of the causes below you are dealing with:
$ ping -c2 host && nc -zv host 22 First confirms the machine is reachable, then tests the specific port. Together they separate "host down" from "port closed" in five seconds.
Causes, ordered by how often they are the culprit
1 The service is not running
The simplest explanation, and the most frequent. It crashed, failed to start after a reboot, or was never enabled.
$ systemctl status theservice $ sudo systemctl start theservice && sudo systemctl enable theservice If it starts and immediately dies, the reason is in journalctl -u theservice -n 50.
2 It listens on 127.0.0.1 instead of 0.0.0.0
A service bound to loopback only accepts local connections. From the machine itself it works perfectly; from outside it is refused. Databases ship this way on purpose.
$ sudo ss -tlnp | grep :5432 $ # in the service config, change the bind address to 0.0.0.0 and restart Think before exposing a database to the network. An SSH tunnel is usually the right answer: ssh -L 5433:localhost:5432 user@server.
3 A firewall is blocking it
ufw, firewalld, iptables, or your cloud provider's security group. Cloud firewalls are the ones people forget, because they live outside the machine.
$ sudo ufw status $ sudo ufw allow 443/tcp Also check the provider console: AWS security groups, DigitalOcean firewalls and Hetzner rules all sit in front of the server and are invisible from inside it.
4 Wrong port or wrong host
The service runs on a non-default port, or DNS points somewhere else than you think.
$ dig +short thehost && sudo ss -tlnp $ ssh -p 2222 user@host 5 The container is not publishing the port
A service inside Docker is unreachable unless the port is mapped to the host.
$ docker ps $ docker run -p 8080:8080 theimage How to stop it happening again
- Enable services so they survive reboots: systemctl enable --now theservice.
- Document which ports each machine should have open, and verify with ss -tlnp after every deployment.
- Keep databases and internal services bound to localhost and reach them over SSH tunnels rather than opening them to the world.
- Add a health check that tests the port from outside the machine, not just from inside it.
Frequently asked questions
What is the difference between "connection refused" and "timed out"?
Refused means something actively answered "no" — the host is up and reachable. Timed out means nothing answered at all: the host is down, unreachable, or a firewall is silently dropping packets.
It works with curl localhost but not from another machine
The service is bound to 127.0.0.1. Change its bind address to 0.0.0.0 — and consider whether it should be exposed at all.
SSH refuses the connection but the server is up
Check that sshd is running (systemctl status ssh), that it is on the port you are using, and that neither the local firewall nor the cloud security group blocks it.
How do I test a port without extra tools?
nc -zv host port is the standard. Without netcat, bash can do it: timeout 2 bash -c "</dev/tcp/host/port" && echo open.
Commands involved
See listening ports, active connections and which process owns each socket.
systemctlStart, stop, enable and inspect services — the control panel of modern Linux.
pingCheck whether a host is reachable and measure round-trip latency.
sshLog into remote machines, run remote commands, use keys instead of passwords, and tunnel ports.
Concepts behind this error: Port · DNS · Daemon
How to do it properly
Move files between machines with scp and rsync, over the same encrypted connection.
Connect to a Linux server with SSHConnect securely to a remote Linux host using username, hostname, port and SSH key.
Other errors
SSH rejected your login because no key you offered was accepted by the server.
bash: command: command not foundThe shell searched every directory in your PATH and found no executable with that name.
No such file or directoryThe path you gave does not resolve — but often the missing part is not the one you think.
Permission deniedThe path resolves fine — the system simply will not let you do that with it.