“localhost refused to connect”: how to find the cause in a minute

“Refused” is good news in disguise: your computer answered straight away and said nothing is listening there. So the fix is to find where your server actually is.

What “refused” means

When the browser connects to localhost:3000, the operating system checks whether any program is listening on port 3000. If none is, it immediately answers with a reset: ERR_CONNECTION_REFUSED in Chrome, “Unable to connect” in Firefox, ECONNREFUSED in Node, Connection refused in curl. It is different from a timeout (something in between dropped the packets, usually a firewall) and from an error page (the server is fine, your code isn't). Want the full trip a request makes? Wirebook's “What happens when you open a web page?” lesson walks through it.

The one-minute checklist

  1. Is the server running? Look at the terminal. A crash on start-up (a syntax error, a missing package, a missing .env value) often scrolls past and leaves nothing listening.
  2. Right port? Copy the URL the server printed rather than typing from memory. Vite uses 5173, Next.js and Create React App 3000, Angular 4200, Flask 5000, Django 8000. If the port was busy, many tools quietly pick the next one (3001, 5174).
  3. http, not https. Dev servers usually speak plain http. Typing https://localhost:3000 fails, and so can a browser that auto-upgrades to https.
  4. Which address is it bound to? localhost can resolve to IPv6 ::1 first. A server bound only to 127.0.0.1 then refuses connections on ::1, or the other way round. Try both http://127.0.0.1:3000 and http://[::1]:3000; Node 17+ changed which one it prefers, which is a common surprise.
  5. Is it really listening? Ask the OS (below). No line for your port means the server isn't up, whatever the terminal says.

See what is listening

SystemCommand
Linuxss -ltnp | grep 3000
macOSlsof -nP -iTCP:3000 -sTCP:LISTEN
Windowsnetstat -ano | findstr :3000
Anycurl -v http://127.0.0.1:3000/

Read the address column: 127.0.0.1:3000 accepts only local connections, 0.0.0.0:3000 or *:3000 accepts all, [::1]:3000 is IPv6 only.

Docker, WSL, VMs and phones

“Address already in use” instead?

That's the opposite problem: something else holds the port, often an old copy of your own server (full walkthrough: EADDRINUSE). Find its process ID with the commands above and stop it (kill PID on macOS and Linux, taskkill /PID n /F on Windows), or start on another port.

Once it connects but answers with an error code, the 401 vs 403 and CORS guides pick up from there.

If the connection works but you get SSL wrong version number, you are using https:// on a plain-HTTP port: see SSL wrong version number.

Does the error mention ::1, or does 127.0.0.1 work while localhost doesn’t? That’s IPv6 vs IPv4: see ECONNREFUSED ::1. Remote SSH timing out rather than a local port refusing? See ssh Connection timed out. Name will not resolve at all (ERR_NAME_NOT_RESOLVED / NXDOMAIN)? See ERR_NAME_NOT_RESOLVED.

Related

Which port is my dev server on? · ERR_EMPTY_RESPONSE · Cloudflare Error 523 · ssh Connection refused port 22 · TypeError: fetch failed (Node) · net::ERR_CONNECTION_TIMED_OUT · HTTP 503 Service Unavailable · ETIMEDOUT / connect ETIMEDOUT · getaddrinfo ENOTFOUND · WebSocket connection failed

Questions

What does ERR_CONNECTION_REFUSED mean on localhost?

Your computer has nothing listening on that port and address. The server isn't running, is on a different port, or is bound to a different address (IPv4 vs IPv6, or inside Docker).

Why does 127.0.0.1 work but localhost doesn't?

localhost may resolve to the IPv6 address ::1 first, and your server listens only on IPv4 127.0.0.1. Use 127.0.0.1 in the URL, or make the server listen on both.

Why can't I reach my Docker app on localhost?

Either the port isn't published with -p or ports:, or the app inside the container listens on 127.0.0.1. It must listen on 0.0.0.0 so the published port can reach it.

How do I open my localhost site on my phone?

Use your computer's local network IP instead of localhost, start the dev server with its host option so it listens on all interfaces, and allow the port in your computer's firewall.

Published · updated .

Try it

Related guides

Newest guides