What it means: The target host answered your connection attempt with a refusal: no process listens on that address and port.
Free online tool — ping & port checker: instant results, no signup.
Pings your host from our server, so you see whether it answers from outside your network.
ECONNREFUSED is the system error «Connection refused». The Linux connect(2) page says a connect() on a stream socket «found no one listening on the remote address», and the Node.js docs add: «This usually results from trying to connect to a service that is inactive on the foreign host.» In Node.js it looks like this:
Error: connect ECONNREFUSED 127.0.0.1:5432
at TCPConnectWrap.afterConnect [as oncomplete] (node:net) {
errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 5432 }The address and port in the message are the most useful part: they show where the client actually tried to connect, which is often not where you think. The host itself is up, since something answered with a refusal; that is what separates this error from ETIMEDOUT, where nothing answers at all. curl reports the same case as exit code 7, «Failed to connect() to host or proxy», and Chrome as ERR_CONNECTION_REFUSED.
| Cause | How to recognise it | Fix |
|---|---|---|
| Service not running or crashed | No process on the port in ss -ltn | Start it; read its logs for why it exited |
| Wrong port | The service listens on another port | Fix the port in config or environment |
| Listening on 127.0.0.1 only | Works on the server, refused from other machines | Bind to 0.0.0.0 or the interface address |
localhost resolves to ::1 | Error shows ::1:3000; server listens on IPv4 only | Use 127.0.0.1 or listen on both families |
localhost inside a container | Works on the host, refused inside Docker | Connect to the other container by its service name |
| Firewall REJECT rule | Refused instantly although the service listens | Allow the port in the firewall |
| Server not ready yet | Fails right after startup, works seconds later | Wait for a health check before connecting |
A common surprise after a Node.js upgrade: connect ECONNREFUSED ::1:3000 while the server is clearly running. In Node.js 17.0.0 the default of dns.lookup()'s verbatim option became true, so addresses are returned in the order the resolver gives them instead of IPv4 first (Node.js dns docs). On many systems localhost resolves to ::1 first, and a server bound only to 127.0.0.1 refuses the IPv6 attempt.
Node.js 20.0.0 and 18.18.0 made autoSelectFamily default to true for net.connect(), which tries the other address family when the first fails (net docs), so the problem shows up less often, but tools and libraries with their own connect logic still hit it. Fixes, in order of preference:
127.0.0.1 explicitly instead of localhost.server.listen(3000, '::') on a dual-stack host).--dns-result-order=ipv4first or dns.setDefaultResultOrder('ipv4first').Inside a container, localhost is the container itself, not your laptop and not the database container. An app container that connects to localhost:5432 gets ECONNREFUSED even though Postgres runs in the next container. On a user-defined network, containers reach each other by name: Docker's bridge network docs state that «User-defined bridges provide automatic DNS resolution between containers», while on the default bridge containers can only reach each other by IP address. In compose, every service gets a name on the project network:
services:
app:
environment:
DATABASE_URL: postgres://app:secret@db:5432/app # not localhost
db:
image: postgres:16Also check the server inside the container: a dev server bound to 127.0.0.1 inside the container refuses connections from the published port. Bind it to 0.0.0.0.
nc -vz 127.0.0.1 5432
curl -v http://127.0.0.1:3000/ss -ltnp | grep -E ':(3000|5432)\b'
# LISTEN 0 511 127.0.0.1:3000 0.0.0.0:* users:(("node",pid=812,fd=21))A listener on 127.0.0.1 only accepts local connections; a missing line means the service is not running.systemctl status app, journalctl -u app -n 50, docker compose ps, docker compose logs db.iptables -S | grep -i reject or nft list ruleset.Browser view of the same problem: ERR_CONNECTION_REFUSED.
nc -vz api.example.com 443
# Connection to api.example.com 443 port [tcp/https] succeeded!Then rerun the client: the error should be gone, or turn into an application-level response. For a public host, the ping and port checker shows whether the port answers from outside your network.
Ping sends ICMP packets to a host and measures response time. Port scanning checks which TCP ports are open and accepting connections — helping diagnose serviceavailability issues.
Choose packet count (3, 4, 6, 10). Stats: min/avg/max latency and packet loss.
Check 14 key ports: HTTP, HTTPS, SSH, FTP, SMTP, MySQL, PostgreSQL, and more.
Testing from our server — see site availability from outside, not just your local network.
Need constant monitoring? Create a monitor — checks every minute with notifications.
availability diagnosis
TCP port scanning
connection debugging
basic health check
Ping check history, host availability monitoring and downtime alerts.
Sign up freeSince Node.js 17, localhost may resolve to the IPv6 address ::1 first. A server listening on 127.0.0.1 only refuses it. Use 127.0.0.1 or listen on both families.
Inside a container localhost is the container itself. Connect to the other container by its service name on a shared user-defined network.
Refused means the host answered and nothing listened on the port. Timed out means nothing answered at all, typically a firewall that silently drops packets.
Sometimes. A REJECT rule produces an immediate refusal, but most cases are a stopped service, a wrong port or a server listening on 127.0.0.1 only.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.