Error reference Libraries

Fix Node.js ECONNREFUSED errors

Error: connect ECONNREFUSED 127.0.0.1:3000 means Node reached the machine and port you asked for — and got an active refusal. Nothing is listening there, or a firewall rejected the attempt. It is not a timeout and not a DNS failure. The address in the message tells you almost everything; here is how to read it and fix the real cause.

Node.js ECONNREFUSED

What ECONNREFUSED means

ECONNREFUSED is a TCP-level error: your connection attempt reached a host, and that host answered with a reset instead of accepting. That distinguishes it from ETIMEDOUT (no answer at all) and ENOTFOUND (DNS never resolved). A machine exists at the IP you dialed, but no process is accepting connections on that port — or a firewall rule is actively rejecting them.

The most useful debugging data is embedded in the message itself: the exact IP and port Node tried. connect ECONNREFUSED 127.0.0.1:5432 during a cloud deploy usually means an environment variable is unset and your code fell back to localhost. connect ECONNREFUSED ::1:3000 is the classic Node 17+ trap: localhost resolved to the IPv6 address ::1, but the server is bound only to 127.0.0.1. Since Node 17, DNS results are no longer reordered to prefer IPv4, so configurations that worked for years started failing.

When a proxy is involved, read the address carefully. If it is your proxy's host and port, the proxy endpoint refused you — wrong port, or a network block between you and it. If it is the target's address, your proxy settings were silently ignored and Node connected directly, which is its own bug to fix.

Node.js ECONNREFUSED

Step-by-step fixes for ECONNREFUSED

Start from the address in the error message and work down. Each step isolates one layer: what Node actually dialed, whether anything listens there, and whether the network in between allows the connection.

  1. Read the IP and port in the error. A 127.0.0.1 or localhost address in production almost always means a missing environment variable made your code fall back to a default.
  2. Verify a listener exists: lsof -i :3000 on macOS/Linux or netstat -ano | findstr :3000 on Windows. No listener means the service is down, crashed at startup, or bound to a different port.
  3. Fix the Node 17+ IPv6 trap: if the error shows ::1, connect to 127.0.0.1 explicitly instead of localhost, or bind the server to both stacks (:: or 0.0.0.0).
  4. In Docker or Compose, localhost inside a container is the container itself. Use the service name as the hostname, and confirm ports are published with -p or a ports: mapping.
  5. Check firewalls and security groups: an actively rejecting rule produces ECONNREFUSED rather than a hang. Test from the machine the code runs on, not from your laptop.
  6. If you are using a proxy, confirm the client actually honors it: Node's built-in fetch ignores HTTP_PROXY unless you wire up an undici ProxyAgent or EnvHttpProxyAgent, and axios has its own proxy quirks.
  7. Reproduce outside Node: curl -v http://host:port/ from the same machine. If curl is also refused, the problem is the environment, not your code.
  8. Confirm the service finished booting before the first request — crash loops and slow starts produce a burst of ECONNREFUSED that resolves seconds later. Add retry-with-backoff for startup dependencies.
Node.js ECONNREFUSED

ECONNREFUSED and proxies: reading the error correctly

With a proxy in the chain there are two distinct TCP connections: yours to the proxy, and the proxy's onward connection to the target. A Node-side ECONNREFUSED can only come from the first hop. If the address in the error is your proxy endpoint, you dialed the wrong host or port, or something on your network blocks it. ProxyOmega's rotating residential entry point is residential.proxyomega.com:10000, and every port serves HTTP, HTTPS, and SOCKS5 — so there is no second port number to guess when you switch protocols.

The subtler failure is the opposite: the error shows the target's address, which proves your traffic never went through the proxy at all. Node's fetch (undici) does not read HTTP_PROXY or HTTPS_PROXY by default, and some axios configurations silently disable proxying. That direct connection may then be refused by a target that only accepts traffic from certain networks — and your proxy never got the chance to help.

Wrong endpoint or port

If the refused address is the proxy's, check it against your dashboard character by character: hostname, port, and scheme. With ProxyOmega the same port carries HTTP, HTTPS, and SOCKS5, so a single working curl test through residential.proxyomega.com:10000 validates the endpoint before you debug any Node code.

Proxy settings silently ignored

Node's built-in fetch requires an explicit dispatcher: new ProxyAgent(url) from undici, or EnvHttpProxyAgent if you want environment variables honored. Without one, fetch dials targets directly. For axios, pass an httpsAgent from https-proxy-agent and set proxy: false so its built-in handling does not conflict.

407 vs ECONNREFUSED: use the difference

A reachable proxy with wrong credentials answers 407 Proxy Authentication Required — an HTTP response, not a socket error. ECONNREFUSED means you never got that far. On ProxyOmega the password is your dashboard API key, or you can whitelist your server's IP and skip credentials entirely; either way, auth mistakes surface as 407, so a refusal points at addressing or network, not credentials.

Node.js ECONNREFUSED

Verify the proxy path end to end

Prove each hop independently: first that the proxy endpoint accepts your connection and credentials with curl, then that Node routes through it via an explicit undici ProxyAgent. When both print an exit IP, the refusal you started with is isolated to whatever address your original code was dialing.

# 1) Prove the proxy endpoint is reachable and credentials work
curl -sS -x "http://USERNAME:[email protected]:10000" \
  https://api.ipify.org
echo

# 2) Prove Node routes through it (fetch needs an explicit dispatcher)
node -e '
const { fetch, ProxyAgent } = require("undici");
const dispatcher = new ProxyAgent(
  "http://USERNAME:[email protected]:10000");
fetch("https://api.ipify.org", { dispatcher })
  .then((r) => r.text())
  .then(console.log);
'
FAQ

Frequently asked questions

What is the difference between ECONNREFUSED and ETIMEDOUT?
ECONNREFUSED is an active rejection: a host at that IP answered your connection attempt with a reset, meaning no process listens on the port or a firewall rejects it. ETIMEDOUT means no answer at all — the host is down, the IP is wrong, or a firewall silently drops packets. The distinction matters: a refusal proves the network path works and only the listener is missing.
Why does localhost fail on Node 17+ when 127.0.0.1 works?
Node 17 stopped reordering DNS results to put IPv4 first, so localhost often resolves to the IPv6 address ::1. If your server bound only to 127.0.0.1, the IPv6 connection attempt is refused. Fix it by connecting to 127.0.0.1 explicitly, binding the server to both stacks, or launching Node with --dns-result-order=ipv4first.
My error shows the target's IP, not my proxy — why?
That means Node never used your proxy. The built-in fetch API ignores HTTP_PROXY and HTTPS_PROXY unless you attach an undici ProxyAgent or EnvHttpProxyAgent, and some axios configurations disable proxying silently. Wire the agent explicitly and re-run: the connection should now originate from the proxy network rather than your machine, and the refusal pattern will change accordingly.
Can a proxy fix ECONNREFUSED from a target server?
Sometimes. If the target refuses connections from your datacenter or cloud IP range at the network level, routing through residential or mobile IPs gives you an address the target accepts. ProxyOmega's rotating residential ports serve HTTP, HTTPS, and SOCKS5 with country targeting, so you can also test whether the refusal is region-specific. If the target service is simply down, no proxy helps.

Connection refused? Not anymore. Start routing today.

Route Node.js traffic through a 90M+ IP network across 200+ countries — HTTP, HTTPS, and SOCKS5 on one port.

ProxyOmega ProxyOmega

90M+ ethically-sourced IPs across 200+ countries and 30,000+ cities. Residential, mobile, ISP and IPv6 proxies for scraping and AI agents.

GDPRCCPA
Product
Premium Unlimited Budget Unlimited Residential / ISP Mobile IPv6 Chrome Extension
Solutions
Web scraping AI agents Price monitoring SERP & SEO Integrations All use cases
Resources
Glossary Error codes Free tools Proxies by platform Locations
Company
About Blog Docs Reseller program Affiliate Contact Sign in
© 2026 ProxyOmega Ltd. All rights reserved.