Short answer:
ERR_CONNECTION_REFUSED
means the server received your request and actively rejected it. The server is reachable at the network level, but nothing is listening on the port you tried to connect to – or something (firewall, security software) is dropping the connection before it completes. This is different from a timeout (where the server never responds) and different from a reset (where the server accepts then immediately cuts the connection).
The fix depends on whether the problem is on your side or the server’s side. This guide covers the 60-second diagnostic to tell them apart, then the specific fix for each cause.
Quick reference#
| If you see | It probably is | Fastest fix |
|---|---|---|
| Refused from every browser, every network | Server-side (web server down, firewall, or crashed) | SSH in,
systemctl status nginx
, restart if down |
| Refused only from your network | Your ISP, local firewall, or router | Try mobile data – if it works there, local issue |
| Refused after site was working | IP banned by fail2ban or WAF | Try a VPN or different IP; unban on server side if you own it |
| Refused in Chrome, works elsewhere | Browser cache, extension, or proxy | Incognito window; disable extensions |
| Refused to localhost:3000 (or similar) | Local dev server not running | Start the service (
npm run dev
, etc.) |
| Refused intermittently | Service crashing and restarting | Check server logs, fix the underlying crash |
How it compares to related browser errors#
Browsers have a handful of connection errors that sound similar but signal different failure modes. Knowing which one you are looking at cuts the diagnosis down before you try any fix.
| Error | What the server did | Speed of failure | Most common cause |
|---|---|---|---|
| ERR_CONNECTION_REFUSED | Sent back
RST
packet immediately | Instant | Web server down, port closed, firewall REJECT |
| ERR_CONNECTION_TIMED_OUT | Never responded at all | ~30 seconds | Server offline, firewall DROP, routing issue |
| ERR_CONNECTION_RESET | Accepted connection, then killed it | 1-10 seconds | Crash mid-request, WAF killing suspicious traffic |
| This site can’t be reached | (Chrome catch-all; sub-code varies) | Varies | DNS failure, network unreachable |
| ERR_NAME_NOT_RESOLVED | Never reached the server at all | Instant | DNS not resolving the domain |
What ERR_CONNECTION_REFUSED actually means#
When your browser tries to open a URL, it opens a TCP connection to the server on port 443 (for HTTPS) or port 80 (for HTTP). That connection starts with a three-way handshake: your browser sends
SYN
, the server replies with
SYN-ACK
, and your browser finishes with
ACK
. Once the handshake completes, the actual HTTP request goes through.
ERR_CONNECTION_REFUSED
happens at the very first step. Your browser sent
SYN
. The server replied with
RST
– a reset packet that explicitly says “I am not accepting connections on this port.” The browser surfaces that as “connection refused.”
This is a specific signal. The server was reachable (your packet got there), the machine was running (something responded), but the port was closed or blocked at the TCP layer. That narrows down the possible causes significantly.
Where each fits:
- ERR_CONNECTION_REFUSED: server actively rejected the TCP handshake (nothing listening or firewall sending RST)
- ERR_CONNECTION_TIMED_OUT: server never responded at all – packets went into the void
- ERR_CONNECTION_RESET: connection started, then got cut mid-transfer
- This site can’t be reached: Chrome’s generic wrapper – can mean any of the above depending on the sub-code
If you see “ERR_CONNECTION_REFUSED” specifically, skip straight to the diagnostic. If the browser just says “can’t reach this site” without a specific code, the cause could be broader.
The 60-second diagnostic#
Before trying fixes, identify whether the problem is your local network, your DNS, or the actual server. Three commands, in order:
# 1. Is DNS returning the right IP?
nslookup example.com
# 2. Can you reach the server at all?
ping example.com
# 3. Is the web port open?
curl -v https://example.com
# or
telnet example.com 443
If nslookup returns no answer: DNS is broken. Try
nslookup example.com 8.8.8.8
to use Google’s DNS directly. If that works, your DNS server is the problem, not the site.
If ping succeeds but curl/telnet shows “Connection refused”: the server is alive, but the web port is closed or blocked. This is the classic refused scenario – skip to Server-side causes.
If ping also fails and curl hangs: this is a timeout, not a refused. The diagnosis switches to the connection timed out article.
If curl connects and returns a response: the server is fine. Your browser is hitting a cached bad state, a proxy issue, or a local extension interfering. Skip to Client-side causes.
Running these three commands cuts the fix down from “it could be anything” to “it is this specific thing” in under a minute.
How long does it take to fix ERR_CONNECTION_REFUSED#
Most causes of
ERR_CONNECTION_REFUSED
resolve in under 15 minutes once you have identified the source. The outliers are DNS propagation and hosting provider issues, which are not under your direct control.
| Cause | Time to fix (once identified) | Notes |
|---|---|---|
Web server stopped (
systemctl start nginx
) | Under 1 minute | The fix is a single command; finding the crash cause takes longer |
| Firewall blocking the port | 2-5 minutes | Add the rule, reload, test |
| Web server bound to localhost instead of 0.0.0.0 | 5 minutes | Edit config, reload, test |
| Fail2ban or WAF banned your IP | 1-2 minutes if you have server access | Unban command is instant; harder if you need to contact support |
| Wrong DNS record | 5 minutes to 24 hours | Edit takes 5 min; propagation depends on TTL |
| Antivirus intercepting | 2-5 minutes | Toggle the web-shield setting, add exception |
| Browser extension blocking | 1 minute | Disable extension or use incognito |
| Local hosts file entry | 2 minutes | Edit file, save, test |
| Service crashing repeatedly | 15 minutes to a few hours | Finding the crash cause is the slow part, not restarting |
| Cloud provider security group misconfigured | 5 minutes | Console click, no deploy needed |
If you have been debugging for more than 20 minutes without progress, you are probably looking at the wrong layer. Restart the diagnostic from the top – nslookup, ping, curl – and trust what the commands tell you rather than what you expected to be true.
Symptom to cause quick lookup#
If you cannot or do not want to run shell commands yet, these symptoms point to specific causes:
| What you observe | Most likely cause |
|---|---|
| Other sites work fine, one specific site refuses | Server-side issue on that specific site |
| All HTTPS sites refuse, HTTP works | Antivirus intercepting HTTPS, or proxy misconfiguration |
| Site worked an hour ago, now refused | Service crashed, your IP got banned, or certificate expired |
| Refused only in Chrome, Firefox works | Chrome-specific extension or cache issue |
| Refused only from work WiFi, home works | Corporate firewall or DNS filtering |
| Refused when using VPN, fine without | VPN server is down, or VPN route cannot reach destination |
Refused to
localhost:PORT
| Local dev service not running on that port |
| Refused with “This site can’t be reached” | Could be DNS, check nslookup first |
Server-side causes#
These are the causes where something is wrong with the destination server. If you are the site owner, start here. If you are a visitor getting refused by a site you do not control, most of these are not fixable from your end – but diagnosing them helps you understand whether to wait, try again, or give up.
Cause 1: The web server is not running
The most common cause. Nginx, Apache, or whatever process handles HTTP requests on the server crashed, failed to restart, or was stopped. Nothing is bound to port 80 or 443, so the kernel responds with RST to every connection attempt.
How to confirm:
# SSH into the server, then:
systemctl status nginx # or apache2, httpd
ss -tlnp | grep ':443' # check what is listening on port 443
If the service is “inactive (dead)” or “failed,” the web server is down. If
ss
shows nothing listening on port 443, same conclusion.
How to fix:
systemctl start nginx
systemctl status nginx
If the start command fails,
journalctl -xeu nginx
will show why. The usual suspects: a config syntax error (run
nginx -t
to check), a port already in use by another process, or a permissions issue on the SSL certificate files.
Cause 2: The firewall is rejecting connections
The server is running, the web server is running, but the firewall is explicitly blocking the port. On Linux servers, this is usually
iptables
or
firewalld
. On cloud hosting, it is the cloud provider’s security group or network ACL.
How to confirm:
# Check local firewall rules
sudo iptables -L -n | grep -E ':(80|443)'
# or for firewalld:
sudo firewall-cmd --list-all
If you see DROP or REJECT rules for ports 80/443, that is the cause. On cloud hosts (AWS, DigitalOcean, Hetzner), also check the provider’s security group – the local firewall might be open while the cloud-level firewall is closed.
How to fix:
# ufw:
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
# firewalld:
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
For cloud-level firewalls, open the provider’s console and check the security group attached to the instance. Rules need to allow inbound TCP on 443 (and 80 if you want HTTP to redirect to HTTPS).
Cause 3: Wrong port or wrong IP
The server is listening, but on a different port than the browser is trying. This usually happens in one of three ways:
- DNS points to a different IP than where the web server actually runs (misconfigured A record or a stale DNS entry after a server move)
- The web server is bound to 127.0.0.1 (localhost) instead of 0.0.0.0 (all interfaces)
- The web server is listening on a non-standard port (8080, 8443) but nothing is forwarding standard ports to it
How to confirm:
# On the server
ss -tlnp | grep nginx # see what Nginx is actually bound to
# From outside the server
nslookup example.com # does DNS point to the right server?
If
ss
shows
127.0.0.1:443
instead of
*:443
or
0.0.0.0:443
, the web server is only accepting connections from the server itself, not from the outside.
How to fix:
In nginx.conf or the vhost file, change:
listen 127.0.0.1:443 ssl;
to:
listen 443 ssl;
Then
nginx -t && systemctl reload nginx
.
If DNS is pointing to the wrong IP, fix the A record at your DNS provider. DNS propagation can take a few minutes to a few hours depending on TTL – be patient after the change.
Cause 4: Service crashed and did not restart
The web server was running, but crashed due to an error. If systemd is configured with
Restart=always
, the service should come back automatically – but on some setups (especially custom-compiled builds or older init systems), a crash leaves nothing running.
How to confirm:
journalctl -xeu nginx --since '1 hour ago'
# or
tail -n 100 /var/log/nginx/error.log
Look for the last few log lines before the service stopped. Common crash causes: out-of-memory (segfault after OOM kill), disk full, configuration reload with a syntax error, or a plugin (for nginx modules or Apache modules) crashing the whole worker pool.
How to fix:
Start the service, then address the underlying cause so it does not crash again:
systemctl start nginx
df -h # check disk space
free -h # check memory
nginx -t # check config
If it is an OOM crash, check which processes are eating memory (
ps aux --sort=-%mem | head -10
). Often a runaway PHP-FPM pool or a memory-leaking plugin is the real cause.
Cause 5: Fail2ban or intrusion detection banned your IP
If you get
ERR_CONNECTION_REFUSED
from a site you were just able to access, your IP may have been banned by an intrusion-detection system. Fail2ban, ModSecurity, and CrowdSec all add firewall rules that drop packets from IPs they consider malicious.
How to confirm (if you have server access):
sudo fail2ban-client status
sudo fail2ban-client status nginx-limit-req # or whichever jail is active
sudo iptables -L -n | grep <your-ip>
If your IP shows up in a ban list, that is why the server is refusing connections – specifically to you, not globally.
How to fix:
- From your side: try from a different network (mobile data, a VPN to a different country). If that works, your original IP is banned.
- From the server side: unban your IP with
sudo fail2ban-client set <jail-name> unbanip <your-ip> - Long-term: find out what triggered the ban. Usually it is repeated failed logins, brute-force attempts, or your scanner triggering a honeypot. Fix the behavior, not just the symptom.
Client-side causes#
If the diagnostic showed curl connecting fine but the browser showing
ERR_CONNECTION_REFUSED
, something local to your machine is intercepting or blocking the request. These causes are all user-side and can be fixed without touching the server.
Cause 6: Local firewall or antivirus blocking
Some antivirus products (Kaspersky, Norton, McAfee) ship with a “web shield” feature that intercepts HTTPS connections for scanning. When it detects something suspicious – or just misidentifies a legitimate site – it blocks the connection and the browser sees it as refused.
How to fix:
- Temporarily disable the antivirus web-protection feature and test
- If the site loads with protection disabled, add an exception for the domain in the antivirus settings
- Windows Defender Firewall, Little Snitch (Mac), and similar tools can also block connections – check their logs
Cause 7: Browser proxy or VPN misconfiguration
If you have a proxy or VPN configured in your browser or OS, and the proxy server itself is unreachable, the browser will report
ERR_CONNECTION_REFUSED
– but the refused connection is to the proxy, not the destination site.
How to fix:
On Windows: Settings > Network > Proxy. Turn “Use a proxy server” off if you did not intentionally configure one.
On Mac: System Settings > Network > select connection > Details > Proxies. Disable all proxies if nothing should be configured.
If you use a VPN, disconnect it and test. If the site loads without VPN, the VPN’s proxy or DNS is the issue.
Cause 8: Browser extension blocking
Ad blockers, privacy extensions, and tracking blockers can be overly aggressive. If an extension has added the site to a block list (or hit a rule that matches the site), the browser refuses the connection before the request leaves your machine.
How to fix:
- Open the site in an incognito/private window (extensions are disabled by default in most browsers)
- If it loads in incognito, disable extensions one by one until you find the culprit
- uBlock Origin, Privacy Badger, and Ghostery are the most common extensions that trigger this
Cause 9: Hosts file entry
Your machine has a local
hosts
file (
/etc/hosts
on Linux/Mac,
C:\Windows\System32\drivers\etc\hosts
on Windows) that overrides DNS for specific domains. If someone (or some software) added an entry pointing the site to
127.0.0.1
or an invalid IP, your browser tries to connect there and gets refused.
How to fix:
Open the hosts file and look for lines mentioning the domain. Remove any entries that do not belong. Malware sometimes edits this file to block security sites or redirect banking sites – if you see suspicious entries, run a malware scan.
Cause 10: Local port conflict (dev environments)
If you are seeing
localhost refused to connect
while doing local development, the local service you are trying to reach is not running.
How to confirm:
lsof -i :3000 # or whichever port your app uses
ps aux | grep node
How to fix:
Start the dev server (
npm run dev
,
rails server
,
php artisan serve
, whatever your stack uses). If the service claims to be running but the port is not bound, check the app’s own logs for startup errors.
How to tell server vs client quickly#
If you have to remember one rule: try the site from a completely different network. Mobile hotspot, a VPN to another country, a friend’s WiFi. If it works there, the problem is local to your original network or machine. If it is refused everywhere, the server is the problem.
This one test cuts through most of the debugging. It is also free and takes 30 seconds.
Complete diagnostic checklist#
Copy this into your notes and work through it top to bottom for any
ERR_CONNECTION_REFUSED
that is not obviously your own dev server.
Step 1 – Confirm the error code. Open DevTools > Network tab, try the page, check the exact error code. “Connection refused” vs “timed out” vs “reset” vs “DNS” each point to different root causes.
Step 2 – Cross-network test. Try the site from a second network (mobile hotspot). If it works there, the issue is local to your current network – jump to step 7.
Step 3 – DNS check.
nslookup example.com
. Is an IP returned? Is it the IP you expect?
Step 4 – Reachability check.
ping example.com
. If packets return, the server is up at the network level. If they do not, you may be looking at a timeout instead of a refused.
Step 5 – Port check.
curl -v https://example.com
or
telnet example.com 443
. Is the TCP handshake failing?
Step 6 – If you have server access.
systemctl status nginx
,
ss -tlnp | grep ':443'
,
sudo iptables -L -n | grep 443
. Does the web server status, port binding, and firewall all look right?
Step 7 – If the issue is local. Disable browser extensions (incognito window), check system proxy settings, check hosts file, temporarily disable antivirus web shield, flush DNS cache (
ipconfig /flushdns
on Windows,
sudo dscacheutil -flushcache
on Mac,
sudo resolvectl flush-caches
on Linux).
Step 8 – Still refused? Check if your IP is on public blocklists (lookup at mxtoolbox.com or similar). If the site owner is using aggressive bot protection, a clean IP or contact with the site owner may be needed.
When to contact your hosting provider#
If you are the site owner and the issue is server-side but you cannot SSH in to diagnose, contact the host. What to include in the ticket:
- The exact error code (
ERR_CONNECTION_REFUSEDspecifically, not just “site down”) - When it started
- The output of
curl -v https://yourdomain.comfrom your machine - Whether you recently changed DNS, added a plugin that affects networking, or changed firewall settings
- Whether it is refused from all IPs or just yours (ask a friend to test from their network)
That last point is the one most customers forget to include. If the site is refused only from your IP but works from every other IP, the server is running fine – something (usually a fail2ban ban or WAF rule) is rejecting your IP specifically. That is a 30-second fix once support knows, versus potentially hours of server-side investigation that will not find anything.
How Hostney handles this#
On Hostney, the container architecture and process management reduce the most common refused scenarios to zero-touch from the customer side:
- Automatic service recovery. If the web server process crashes, systemd restarts it within seconds. The “service crashed and did not restart” cause is handled by the platform.
- Managed firewall rules. Ports 80 and 443 are open at all infrastructure layers by default. Customers do not configure firewalls manually for standard web traffic.
- Monitoring with alerting. The platform monitors service health continuously. If something does go wrong at the infrastructure layer, it is usually fixed before customers notice.
- Per-site container isolation. One customer’s site crashing or being DoS’d cannot refuse connections on another customer’s site.
What we cannot fix from the platform side is client-side causes (local firewall, browser extensions, VPN issues, hosts file entries, ISP blocks). Those are always going to require user-side diagnosis.
Summary#
ERR_CONNECTION_REFUSED
is a specific signal: the server is reachable, but the port is closed or actively blocked. That narrows the possible causes to 10 common ones, split roughly 50/50 between server-side (web server down, firewall, wrong bind address, crash, IP ban) and client-side (local firewall, proxy, extension, hosts file, dev server not running).
The 60-second diagnostic (nslookup + ping + curl/telnet) tells you which side is the problem. From there, the fix is usually one or two commands away. If you are seeing this as a site visitor, trying from a different network is the fastest way to know whether to wait for the site owner to fix it or to look at your own setup.
For related browser errors, see ERR_CONNECTION_TIMED_OUT for the timeout case, ERR_CONNECTION_RESET for connections that start then get cut, and this site can’t be reached for the Chrome catch-all. If the refused error is specifically on SSH rather than a browser, SSH connection refused covers that scenario with the same diagnostic approach.