ERR_CONNECTION_REFUSED: What It Means and How to Fix It
Connection refused means your browser reached the computer, but nothing was listening on that port. The causes on localhost (dev server not running, wrong port, crashed) and on a live site (app or web server down, firewall, wrong address), and how to check each.
This site can't be reached
localhost refused to connect.
ERR_CONNECTION_REFUSED
Connection refused is quite specific: your browser found the computer, knocked on the port, and nothing answered — no program was listening there, or something actively rejected the connection.
That's different from a timeout (nothing reachable at all) or a DNS error (couldn't find the computer). (This site can't be reached)
On localhost (during development)
1. The dev server isn't running
The most common cause by far. Check the terminal where you ran npm run dev — did it stop, crash, or never start? Start it again and read any error it prints. (npm run dev vs build)
2. Wrong port
Your app is running, but on a different port than the one in your browser. Vite uses 5173, Next.js and Create React App 3000, Django 8000, Flask 5000. The terminal tells you the exact URL — use that one. (What is localhost?, Ports explained)
If the port was busy, some tools silently pick the next one (3001, 5174).
3. It crashed on start-up
The server started, hit an error (missing environment variable, database not running), and exited. Scroll up in the terminal.
4. IPv4 vs IPv6
Sometimes localhost resolves to ::1 (IPv6) but the server listens only on 127.0.0.1 (IPv4), or the other way round. Try http://127.0.0.1:3000 instead of http://localhost:3000. (IPv4 vs IPv6)
5. Inside Docker
A server inside a container must listen on 0.0.0.0, not localhost, and the port must be published (-p 3000:3000). Otherwise it's unreachable from your browser. (What is Docker?)
On a live site
If your real domain gives connection refused:
1. The web server isn't running
Nginx, Caddy or your app process stopped. On the server:
sudo systemctl status nginx
pm2 ls # or systemctl status myapp
2. Nothing is listening on 80/443
Check what's listening:
sudo ss -tlnp
You should see something on :80 and :443. If not, your web server isn't up or isn't configured for those ports.
3. A firewall is rejecting it
The server's firewall (UFW), your cloud provider's firewall, or a security group may be blocking ports 80/443. (UFW firewall basics)
4. DNS points at the wrong server
The domain resolves to an old IP where nothing runs any more. Check with dig yourdomain.com. (What is a DNS server?)
5. HTTP vs HTTPS
The site only listens on 443 and you typed http://, or the other way round, with no redirect set up.
For APIs and databases
The same idea appears in code as ECONNREFUSED:
Error: connect ECONNREFUSED 127.0.0.1:5432
Your app tried to reach a database (5432 is Postgres) or another service, and nothing was listening. (ECONNREFUSED explained)
Quick checklist
- Is the server process running?
- Is it on the port you're using?
- Is it listening on the right address (
0.0.0.0in containers)? - Is a firewall blocking the port?
- Does DNS point at the right machine?
EasySpawn keeps your app running and restarts it if it crashes, with the web server, ports and firewall already set up — so "connection refused" is rare and easy to diagnose when it happens. See how it works or join the waitlist.
Related: What Is Localhost? · What Is an IP Address and a Port? · 502 Bad Gateway · ECONNREFUSED 127.0.0.1:5432
Keep reading
"Your Connection Is Not Private" on Your Own Site: Causes and Fixes
When visitors see NET::ERR_CERT_DATE_INVALID, ERR_CERT_COMMON_NAME_INVALID or ERR_CERT_AUTHORITY_INVALID on your site, the SSL certificate is expired, for the wrong name, or incomplete. How to tell which, and how to fix each one.
"ReferenceError: window is not defined" in Next.js: How to Fix It
window, document and localStorage only exist in the browser. Next.js renders components on the server first, where they don't exist. Why it happens, and the fixes: useEffect, 'use client', typeof checks, dynamic imports with ssr: false, and libraries that touch window on import.