ETIMEDOUT / connect ETIMEDOUT (Node fetch, axios, database)

A client tried to open a TCP connection (or waited for a response) and gave up. ETIMEDOUT means silence — nothing accepted or answered in time — not a clean “connection refused” reset.

What ETIMEDOUT means

In Node (libuv) Error: connect ETIMEDOUT is errno ETIMEDOUT: SYN packets got no accepting handshake before the connect timeout. Libraries wrap it as axios ETIMEDOUT, undici/fetch failures, SequelizeConnectionError, MongoServerSelectionError: … timed out, Redis Connection timeout, etc. A request timeout (response headers never arrived) is related but configured separately from the TCP connect timeout.

Error: connect ETIMEDOUT 203.0.113.10:5432
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:…)
# axios: error.code === 'ETIMEDOUT'
# fetch: TypeError: fetch failed → cause.code === 'ETIMEDOUT'

ETIMEDOUT vs ECONNREFUSED vs others

CodeWhat happenedTypical meaning
ETIMEDOUTNo reply in timeFiltered port, wrong network path, host down blackhole, very slow route
ECONNREFUSEDTCP RST / nothing listeningWrong port or process not started — see ECONNREFUSED
ENOTFOUNDDNS failedBad hostname — see ERR_NAME_NOT_RESOLVED
ECONNRESETPeer closed mid-streamProxy/LB idle timeout, server crash, TLS mismatch fallout
ERR_SOCKET_TIMEOUT / undiciHeaders/body wait exceededRaise timeout only after fixing the slow dependency

Cause table

SituationLikely causeFix
DB/API from app serverSecurity group / firewall drops packetsAllow app → DB port; avoid 0.0.0.0 open; check NACLs
Works locally, fails in Dockerlocalhost is the containerUse service name / host.docker.internal / host gateway IP
HTTPS URL to HTTP portTLS speaking to plain socket (often hangs then fails)Match scheme and port; see SSL guides
Corporate laptopHTTP_PROXY/HTTPS_PROXY required or brokenSet or unset proxy env; configure NO_PROXY for internal hosts
IPv6 AAAA firstBroken IPv6 pathTry IPv4 literal; fix dual-stack; compare with curl -4/-6
Server under loadAccept queue / DB connections exhaustedMetrics, pool sizes, scale; don’t only raise client timeout

Debug steps

  1. From the same machine/container as the app: curl -v --connect-timeout 5 host:port or nc -vz host port.
  2. Confirm DNS: getent hosts name / dig — wrong IP is a silent timeout later.
  3. Compare connect vs whole-request timeouts in your client (axios.timeout, undici connectTimeout, DB pool acquire).
  4. Check firewalls both ways and whether the service listens on 127.0.0.1 only vs 0.0.0.0.
  5. If it is intermittent, look at load balancers’ idle timeouts and connection pooling.
# Quick TCP check (Linux)
nc -vz db.internal 5432
curl -v --connect-timeout 5 https://api.example.com/health

# axios: surface the code
try {
  await axios.get(url, { timeout: 10_000 });
} catch (err) {
  console.error(err.code, err.cause?.code, err.message);
}

Related networking pages: ECONNREFUSED, localhost refused to connect, TypeError: Failed to fetch, ERR_NAME_NOT_RESOLVED, too many redirects.

Related

TypeError: fetch failed (Node) · net::ERR_CONNECTION_TIMED_OUT · HTTP 504 Gateway Timeout · getaddrinfo ENOTFOUND · ECONNRESET · WebSocket connection failed · HTTP 206 Partial Content · download won't resume

Questions

What does connect ETIMEDOUT mean in Node?

The TCP handshake (or configured connect wait) expired without a successful connection — usually firewall, wrong network, or a host that never answers.

How is ETIMEDOUT different from ECONNREFUSED?

REFUSED means something answered with a reset (nothing listening). TIMED OUT means silence / filtered path.

Why does it work on my laptop but time out in production?

Different VPC/security groups, private DNS, or proxy requirements. Debug from the production network namespace.

Should I just increase the timeout?

Only after checking connectivity. A higher timeout on a blackholed port just makes failures slower.

Can DNS cause ETIMEDOUT?

Bad DNS usually shows ENOTFOUND first. A resolved-but-unreachable IP then times out on connect.

Do Docker and localhost interact badly here?

Yes — localhost inside a container is not the host. Use the compose service name or a host gateway.

Published .

Try it

Related guides

Newest guides