ERR_CONNECTION_REFUSED: what it means and how to fix it
Kofi Agyem, Founder and CEO, CloudzyroPublished · 5 min read
On this page
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.1refuses 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
::1or 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
- Check the address, especially any port number after the domain, like
:8080. - Reload after a minute, in case the server was restarting.
- 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.
- Turn off your VPN and try again.
- 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
- Check the dev server is running and didn't crash. Read the last lines in its terminal.
- 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.
- Try `127.0.0.1` instead of `localhost`, or start the server listening on all addresses. Since Node 17,
localhostcan resolve to the IPv6 address::1first, so a server on127.0.0.1only can be refused. - In Docker, publish the port (
-p 3000:3000) and make the app listen on0.0.0.0inside the container, not127.0.0.1. - In WSL or a VM, connect to the address the environment gives you if
localhostforwarding 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
- Check the web server is running and restart it. Read its logs for why it stopped.
- Check it listens on 80 and 443 on the public address (
ss -tlnp). - Check the firewall allows both ports, and that it's not set to reject them.
- Check DNS points the name at this server, for both IPv4 (A) and IPv6 (AAAA).
- 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.
docker psshows the container running with0.0.0.0:3000->3000/tcp, so the port is published.docker logsshowsListening 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.- 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.