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

Linux Error: Connection refused — Cause, Fix, and Troubleshooting Guide

How to fix the Linux 'Connection refused' error (ECONNREFUSED): diagnose closed ports, dead services, wrong bind address and firewalls with ss, curl and nc.

  • #linux
  • #troubleshooting
  • #networking

Summary

Connection refused is the errno ECONNREFUSED (111): the packet reached the target host, but nothing was listening on that port, so the kernel replied with a TCP RST. Crucially the host is reachable — DNS resolved and routing worked — the service is the problem. This makes it fast (an immediate rejection, not a timeout) and distinct from Connection timed out, where packets are silently dropped.

Common Symptoms

  • curl / nc / a client library returns Connection refused immediately, with no delay.
  • The app connects fine to other ports on the same host but not this one.
  • ping <host> succeeds; only the specific TCP/UDP port is refused.
  • Works from localhost but not from another machine (a bind-address issue).

Most Likely Causes of the ‘Connection refused’ Error

  1. The service is not running — it crashed, failed to start, or was never started.
  2. Service bound to 127.0.0.1 only — it listens on loopback, so remote clients get refused.
  3. Wrong port — the client targets a port the server does not listen on.
  4. Service still starting / not yet listening — race on boot or during a deploy.
  5. Firewall REJECT rule (as opposed to DROP) — an explicit reject returns an RST that looks like refused.
  6. Proxy/loadbalancer with no healthy backend returning a refusal.

Quick Triage

# Reproduce and confirm it is instant (refused, not timeout)
curl -v http://<host>:<port>/
nc -vz <host> <port>

# Is anything listening on that port locally?
ss -tulpn | grep ':<port>'

# Is the service even up?
systemctl status <service>

Diagnostic Commands

# What is listening, on which address, and which PID (ss; use -tulpn)
ss -tulpn | grep ':<port>'
# RHEL/older hosts without ss:
sudo netstat -tulpn | grep ':<port>'

# Service state and recent crash logs
systemctl status <service>
journalctl -u <service> --since "15 min ago" -n 50

# Probe the port from a client, verbosely
nc -vz <host> <port>
curl -v http://<host>:<port>/

# DNS + routing are fine for 'refused', but confirm you hit the right host
getent hosts <host>
ip route get <host-ip>

# Firewall rules that could REJECT
sudo iptables -S | grep -i reject
sudo nft list ruleset 2>/dev/null | grep -i reject
sudo firewall-cmd --list-all      # RHEL/Rocky firewalld

If ss -tulpn shows the service bound to 127.0.0.1:<port>, remote clients will always be refused even though local curl works.

Fix / Remediation

  1. Start (or restart) the service:

    sudo systemctl start <service>
    systemctl status <service>
    ss -tulpn | grep ':<port>'
  2. Fix the bind address so it listens on all interfaces (or the intended one). Change the app config from 127.0.0.1 to 0.0.0.0 (or the specific IP), e.g. nginx listen 0.0.0.0:8080;, then restart:

    sudo systemctl restart <service>
    ss -tulpn | grep ':<port>'   # confirm 0.0.0.0:<port> or the LAN IP

    Warning: Binding a service to 0.0.0.0 exposes it on every interface. Make sure a firewall or security group restricts who can reach it before exposing management or database ports publicly.

  3. Correct the client’s target port if ss shows the service on a different port than the client uses.

  4. Fix a REJECT firewall rule (Ubuntu ufw / RHEL firewalld):

    sudo ufw allow <port>/tcp                        # Ubuntu/Debian
    sudo firewall-cmd --add-port=<port>/tcp --permanent && sudo firewall-cmd --reload   # RHEL/Rocky
  5. Add startup ordering/health gating if the refusal is a boot race — make dependents wait for the port to be listening.

Validation

ss -tulpn | grep ':<port>'                 # service listening on the right address
nc -vz <host> <port>                       # succeeds
curl -sS -o /dev/null -w '%{http_code}\n' http://<host>:<port>/

Prevention

  • Health-check the actual listening port (not just the process) and alert when it stops accepting connections.
  • Make bind addresses explicit in config and reviewed — loopback-only binds are a common regression.
  • Add client-side retries with backoff so brief restarts do not fail requests hard.
  • Use systemd After=/readiness gates so dependents start only once the port is up.

Final Notes

Connection refused means “I reached the host but nobody answered on that port” — an RST, not a drop — so focus on the service, its bind address, and the port, not on routing or DNS. ss -tulpn plus systemctl status resolves the vast majority of cases in under a minute.

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

Download the Free 500-Prompt DevOps AI Toolkit

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.