Back to blog
uptime

ERR_CONNECTION_REFUSED: how to fix it

Fix connection refused errors by checking if the service is listening, the port is correct, and DNS points to the right server.

Sandeep Sidhu

· Founder, AlertKick

6 min read
ERR_CONNECTION_REFUSED: how to fix it

You see “This site can’t be reached - example.com refused to connect - ERR_CONNECTION_REFUSED” in Chrome. Or you are the site owner watching support tickets pile up because the service stopped listening. The error is immediate and specific: the network path works, but nothing is there to take the call.

This is not a timeout. Silence means packets are lost somewhere on the route. A refusal means a machine answered with a RST packet, saying “nothing is listening on this port.” That immediacy is diagnostic gold. It tells you exactly where to look next.

The fix depends on who you are. If you are a visitor, the issue is likely your local DNS, proxy, or a typo in the URL. If you own the site, the service crashed, failed to bind to the right interface, or DNS is pointing clients to the wrong box. Here is how to tell the difference and fix it.

What ERR_CONNECTION_REFUSED means

The client’s TCP SYN reached a machine, and that machine answered immediately with a RST packet. Nothing is listening on this port. This is an active rejection. It is the opposite of a timeout, which is silence.

A refusal means the network path works and a machine answered, but no process is bound to the port, or a firewall is sending a REJECT instead of a DROP. A timeout means packets are vanishing somewhere on the path.

The error looks consistent across tools. curl exits with code 7 (“Failed to connect … Connection refused”). Applications see the ECONNREFUSED error code. Browsers display “This site can’t be reached - example.com refused to connect - ERR_CONNECTION_REFUSED”.

Three stories usually explain this state. First, the service is not running. It crashed, a deploy failed, or it was never enabled to start on boot. Second, the service is running but bound to the wrong interface or port. Third, DNS is sending clients to the wrong machine entirely. The target box is up, but it has never heard of the site.

Understanding this distinction separates the visitor from the owner. Visitors face local DNS, proxy, or URL typos. Owners face crashed services, binding errors, or stale DNS records. The next step is determining if the refusal is global or local.

Is the error global or local?

Determine if the refusal affects everyone or just you. This split tells you whether to look at your own machine or at the server.

Test from an external network using AlertKick’s free website down checker. No signup is required. The tool reports up/down status, HTTP response codes, redirect chains, and DNS/TCP/TLS timing.

If the checker also sees a refusal, the problem is server-side. The service is down, misconfigured, or blocked. Look at the host.

If the checker reports the site is fine, the visitor’s own machine or network is the bottleneck. The issue is local to the client.

This distinction saves time. It prevents restarting services when the problem is a stale DNS record on a user’s laptop. It stops you from blaming the network when the web server has crashed.

For visitors, the next step is a checklist of local causes. Typos in the URL, stale DNS caches, or dead proxy settings are common culprits. These are easy to fix on the client side.

For owners, the next step is to put the listener back. Check if the process is alive, verify interface bindings, and review firewall rules. These are server-side fixes.

Visitor-side checks

The error often lives on the client side. Before blaming the server, rule out local configuration issues.

Check the URL and port first. A typo like using https on a port serving plain HTTP, or an explicit :8080 that is no longer in use, refuses the connection instantly.

Stale DNS records point clients at machines that no longer run the site. Flush the local cache and compare answers.

dig +short example.com
dig +short example.com @1.1.1.1

On Windows, run ipconfig /flushdns. On macOS, run sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder. On Linux, run sudo resolvectl flush-caches.

Check the hosts file for leftover overrides. These files can point a domain at 127.0.0.1 or a dead IP. Look in /etc/hosts on Linux and macOS, or C:\Windows\System32\drivers\etc\hosts on Windows.

Disable proxy settings. Both system-level proxies and browser extensions can interfere. A dead proxy refuses every connection while the actual sites remain fine.

Split device versus network issues in one step. Try another device on the same network, then try a phone hotspot. If the error follows the device, the problem is local. If it follows the network, the issue is upstream.

Fixing localhost refused to connect

“localhost refused to connect” means nothing is listening on that port on your machine. The dev server is not started, crashed on boot, or is listening on a different port than the URL.

Check whether anything is bound to the port and which process owns it. On Linux, run:

ss -tlnp | grep :<port>

On macOS, use:

lsof -iTCP -sTCP:LISTEN -P | grep <port>

If the output is empty, the service is not running. Start it. If the output shows a process, note the port and interface.

Framework dev servers often bind 127.0.0.1 only. This makes the service reachable as localhost but refused from other devices on the LAN. Bind 0.0.0.0 to expose it to the network. Do this for development only. Never expose a dev server to the internet without a firewall in front.

If the service is running on the correct port but still refuses, check the URL. A typo like https on a port serving plain HTTP, or an explicit :8080 that is no longer in use, refuses instantly. Verify the port number matches the process binding.

If the service is running and bound correctly, check for port conflicts. Another process may have taken the port. The ss or lsof output will show the PID. Kill the conflicting process or reconfigure the service to use a different port.

Restart the service after making changes. Verify the binding again with the same command. Ensure the process is listening on the expected interface and port.

Owner-side fixes

Is the process alive? Run systemctl status nginx (or whatever serves the port). Crashed and failed-on-boot services are the number one cause. Restart AND enable: sudo systemctl enable --now nginx. Read why it died first: journalctl -u nginx -n 50.

Is it bound where the internet arrives? Run ss -tlnp | grep -E ':(80|443)'. A listener on 127.0.0.1:443 answers curl on the box and refuses the world. The paired test proves it: curl -sI https://localhost succeeding while curl -sI https://<public-ip> is refused = interface binding problem.

In containers, a missing or wrong port mapping refuses from outside while the app runs happily inside: docker ps --format '{{.Names}}\t{{.Ports}}' - no 0.0.0.0:443->... mapping means the port was never published.

Firewall REJECT rules (as opposed to DROP) produce refused, not timeout: sudo iptables -L -n | grep -i reject or sudo nft list ruleset | grep -i reject, and sudo ufw status on Ubuntu.

After a failed certificate renewal, web servers can refuse to start entirely - check journalctl -u nginx -n 50 for “cannot load certificate”. Fix the cert path, then restart.

DNS pointing at the wrong box after a migration: dig +short example.com and compare with the server’s actual public IP. If they differ, every visitor is knocking on a stranger’s door.

Preventing future downtime

Connection refused after a reboot or deploy is invisible until someone tries the site. A scheduled check finds it in minutes. AlertKick monitors check from EU and US regions on an interval, record the failing phase, and alert by email, Slack, Telegram, or WhatsApp, with escalation chains for teams. Uptime monitors are included in the free plan.

Pair the monitor with a boot-time habit: systemctl enable everything that must survive a reboot, then let the monitor prove it did.

When a service crashes or fails to start, the monitor detects the refusal immediately. The team receives an alert before users notice.

Use the free website down checker to verify the setup. It reports up/down status, HTTP status codes, redirect chains, and DNS/TCP/TLS/first-byte timing. No signup is required.

For deeper context, read the guide on connection timeouts. That error indicates silence, not refusal. Understanding the difference helps diagnose network paths versus service availability.

Also review the checks every server should have on day one. This post covers essential baseline checks for any server.

Frequently asked questions

What does ERR_CONNECTION_REFUSED mean?
The client's TCP SYN reached a machine, and that machine answered immediately with a RST packet. This active rejection means the network path works, but no process is listening on the target port. It is the opposite of a timeout, which results in silence.
How can I tell if the error is on my end or the server's end?
Test the site from an external network using AlertKick's free checker at https://alertkick.com/tools/website-check. If the checker also sees a refusal, the problem is server-side. If the checker reports the site is fine, the issue is local to your machine or network.
Why does localhost refused to connect appear on my own machine?
This means nothing is listening on that specific port on your computer. The development server may not be started, crashed, or is bound to a different port. Use `ss -tlnp` or `lsof` to verify if a process is bound to the expected port.
What should I do if the service is running but the site still refuses connections?
Check if the service is bound to the correct interface. A listener on 127.0.0.1 answers curl on the box but refuses connections from the internet. Verify the binding with `ss -tlnp` and ensure it is listening on 0.0.0.0 or the public IP.
Can firewall rules cause ERR_CONNECTION_REFUSED?
Yes, firewall REJECT rules produce a refused error, while DROP rules cause a timeout. Check for reject rules using `sudo iptables -L -n | grep -i reject` or `sudo ufw status`. A REJECT rule actively sends a RST packet back to the client.
How do I prevent this error after a server reboot?
Enable the service to start on boot using `systemctl enable`. Pair this with a scheduled uptime monitor like AlertKick to detect refusals immediately. The monitor checks from EU and US regions and alerts the team via email, Slack, or Telegram.
uptime monitoring troubleshooting