"ERR_CONNECTION_REFUSED" — Nothing Is Listening on That Port

Connection refused means the host was reachable but nothing accepted the connection on that port. This walk-through separates 'service down' from 'wrong port' from 'firewall reject'.

What you'll see

Root causes

The service isn't running or isn't bound where you think

Check the listener: ss -tlnp | grep :PORT. A common trap: the app binds to 127.0.0.1 only, so remote connections are refused while localhost works.

Wrong port or the service moved

Configs drift — the app may run on 8080 while you connect to 8081, or the container published a different host port than the container port.

Firewall actively rejecting (REJECT rule)

REJECT returns a refusal (connection refused) rather than dropping (timeout). Check: sudo iptables -L -n | grep -i reject and ufw status verbose.

Fix it

  1. Confirm what's actually listening
    ss -tlnp | grep -E ':(80|443|8080|3000)\b'   # look at the Local Address column
  2. Test from the host itself, then remotely
    curl -v http://127.0.0.1:3000/  # works locally but not remotely = bind address problem
  3. Make the service bind all interfaces (or the right one)
    # typical app flags: --host 0.0.0.0   |   app.listen(3000, '0.0.0.0')   |   docker run -p 3000:3000
  4. Rule out the firewall
    sudo ufw status && sudo ufw allow 3000/tcp   # or check cloud security-group rules

Field note

Refused vs. timeout is diagnostic gold: refused = reachable host, no listener; timeout = packets dropped or host/route down. In containers, -p host:container port mapping is a frequent source of 'works on my machine' refusals.

Common questions

Connection refused but the service logs look healthy?

The service is probably listening only on 127.0.0.1. Run ss -tlnp — if the local address is 127.0.0.1:3000, remote clients will always be refused. Bind 0.0.0.0 (and firewall it properly).

Does DNS play a role in connection refused?

No — if DNS failed you'd get name-resolution errors. Refused means TCP reached a live host and got an RST back. Use dig +short <host> to rule out resolving to the wrong IP.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.

Get new fixes by email

One short email when new fixes and production templates drop. No spam, unsubscribe anytime.

Partner pick — sponsored

Vultr — our lab-environment pick for this stack

Spin up a cloud server in 60 seconds and reproduce this fix yourself — pay by the hour.

Get Vultr →
Also vetted

Sentry — Free tier: see the exact line of code that broke, before users report it.

Get Sentry →

We earn a commission if you buy through our links — it never costs you extra. More vetted tools on our picks hub · comparing clouds? DigitalOcean vs Vultr and vs AWS · full deals: DigitalOcean · Vultr · NordLayer · Semrush