Skip to content
Cloudzyro
Troubleshooting

ERR_CONNECTION_REFUSED: what it means and how to fix it

Kofi Agyem

, Founder and CEO, CloudzyroPublished · 5 min read

On this page
  1. 1. The short answer
  2. 2. What you'll see
  3. 3. What causes it
  4. 4. Fixes for visitors, quickest first
  5. 5. Fixes for developers on localhost
  6. 6. Fixes for site owners
  7. 7. A worked example
  8. 8. How to check
  9. 9. Sources

ERR_CONNECTION_REFUSED means the server said no to the connection, usually because nothing is listening. Fixes for visitors, site owners and localhost.

1. The short answer

ERR_CONNECTION_REFUSED means your browser reached the server, but the server rejected the connection. Its operating system replied with a TCP reset to the very first packet, which means no program is listening on that port, or a firewall is set to reject rather than ignore.

For a public site, this is almost always the site's problem: its web server is stopped or misconfigured. On your own computer, it's usually a development server on localhost that isn't running or is on a different port. It belongs to the This site can't be reached family.

2. What you'll see

  • Chrome: This site can't be reached. example.com refused to connect. ERR_CONNECTION_REFUSED.
  • Edge: Hmm... can't reach this page. example.com refused to connect.
  • Firefox: Unable to connect. Firefox can't establish a connection to the server at example.com.
  • Safari: Safari can't open the page because Safari can't connect to the server.
  • curl: Failed to connect to localhost port 3000: Connection refused.

3. What causes it

  • The web server isn't running. nginx, Apache, Caddy or your Node app stopped or failed to start.
  • It's listening on a different port. The app runs on 8080 and you're connecting to 3000, or HTTPS isn't set up on 443.
  • It's listening only on localhost. A server bound to 127.0.0.1 refuses connections that arrive on the machine's public address, including from a proxy in another container.
  • IPv4 and IPv6 don't match. The name resolves to ::1 or an IPv6 address, and the server only listens on IPv4, or the other way round.
  • A firewall rejects the port instead of dropping it.
  • DNS points to the wrong server, one that's up but doesn't run your site.
  • A broken proxy setting on your device. If the browser is set to use a proxy that isn't running, every site is refused.

4. Fixes for visitors, quickest first

  1. Check the address, especially any port number after the domain, like :8080.
  2. Reload after a minute, in case the server was restarting.
  3. Check your proxy settings. Windows: Settings, Network and internet, Proxy. Mac: System Settings, Network, your connection, Details, Proxies. Turn off any you didn't set.
  4. Turn off your VPN and try again.
  5. Try another network or device. If it fails everywhere, the server is refusing everyone and only the owner can fix it.

5. Fixes for developers on localhost

  1. Check the dev server is running and didn't crash. Read the last lines in its terminal.
  2. Use the address it prints. Vite defaults to port 5173, Next.js and many Node apps to 3000, and the port changes if the default is taken.
  3. Try `127.0.0.1` instead of `localhost`, or start the server listening on all addresses. Since Node 17, localhost can resolve to the IPv6 address ::1 first, so a server on 127.0.0.1 only can be refused.
  4. In Docker, publish the port (-p 3000:3000) and make the app listen on 0.0.0.0 inside the container, not 127.0.0.1.
  5. In WSL or a VM, connect to the address the environment gives you if localhost forwarding is off.
# What's listening, and on which address?
lsof -iTCP -sTCP:LISTEN -n -P          # macOS
sudo ss -tlnp                          # Linux
netstat -ano | findstr LISTENING       # Windows

# Make a Node server reachable from outside its container
app.listen(process.env.PORT || 3000, "0.0.0.0");

6. Fixes for site owners

  1. Check the web server is running and restart it. Read its logs for why it stopped.
  2. Check it listens on 80 and 443 on the public address (ss -tlnp).
  3. Check the firewall allows both ports, and that it's not set to reject them.
  4. Check DNS points the name at this server, for both IPv4 (A) and IPv6 (AAAA).
  5. If a proxy sits in front, check the proxy can reach the app on the port it's configured for. A refused connection behind a proxy usually shows to visitors as a 502 Bad Gateway rather than this error.

On Cloudzyro Sites & Apps, we run the web servers, so a refused connection on your domain means its DNS points somewhere else, such as a previous host. Set www as a CNAME to domains.cloudzyro.app and the bare domain's A record to 173.234.137.167. If your Node app doesn't listen on the port in PORT, the deploy fails with a plain explanation and the previous version keeps serving.

7. A worked example

A developer containerizes a Node app. It runs fine with npm start on their laptop, but in Docker, http://localhost:3000 gives ERR_CONNECTION_REFUSED.

  1. docker ps shows the container running with 0.0.0.0:3000->3000/tcp, so the port is published.
  2. docker logs shows Listening on http://127.0.0.1:3000. Inside the container, 127.0.0.1 means the container itself, so connections forwarded from outside are refused.
  3. They change the app to listen on 0.0.0.0, rebuild, and the page loads.

The same mistake on a real server, with the app on 127.0.0.1 and a proxy connecting from another container, shows visitors a 502 Bad Gateway instead of a refusal.

8. How to check

# Where does the name point?
dig +short www.example.com

# Is the port open? "refused" confirms nothing is accepting connections
nc -vz www.example.com 443                              # macOS and Linux
Test-NetConnection www.example.com -Port 443            # Windows PowerShell

# Full detail of the attempt
curl -v https://www.example.com/

A refusal from the public address but success from the server itself (curl -v http://127.0.0.1:3000) means the app is listening only on localhost, or a firewall rejects outside traffic. A refusal from everywhere means it isn't running on that port at all.

9. Sources

Questions

What does ERR_CONNECTION_REFUSED mean?
Your browser reached the server's address, but the server rejected the connection on that port. Usually no program is listening there, or a firewall is set to reject connections.
Why do I get ERR_CONNECTION_REFUSED on localhost?
Your development server isn't running, is on a different port, or crashed. Check the terminal where you started it, and open the exact address and port it prints.
Is it my fault or the website's?
For public sites it's nearly always the website's server. On your side, a misconfigured proxy setting or VPN can cause it, so try another network to be sure.
How do I fix ERR_CONNECTION_REFUSED in Chrome?
Check the address and port, turn off any proxy or VPN, try an incognito window and another network. If it still fails, the site's server isn't accepting connections and only its owner can fix it.
What's the difference between refused and timed out?
Refused is a fast no: the server's system replied that nothing accepts connections there. Timed out is silence: no reply at all, often because a firewall drops the packets.
Why does localhost work in the browser but not in my code?
Since Node 17, localhost may resolve to the IPv6 address ::1 first. If your server listens only on 127.0.0.1, a client connecting to ::1 gets connection refused. Listen on both, or connect to 127.0.0.1.

Put your site online free

From your AI tool, Git or a zip, with every version kept.