Skip to content
Latchkey

Node.js "read ECONNRESET" - Flaky HTTP Test in CI

The remote side reset the TCP connection while Node was reading from it. In CI this is a classic flaky-test failure - a keep-alive socket closed, a proxy dropped the connection, or the network blipped.

What this error means

An HTTP test intermittently fails with read ECONNRESET. Re-running the same job usually passes, which is the signature of a transient connection reset rather than a real bug.

node
Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
  errno: -104,
  code: 'ECONNRESET',
  syscall: 'read'

Common causes

The peer closed a keep-alive connection

A server or proxy closed an idle keep-alive socket just as the client reused it, producing a reset mid-read. This is intermittent.

A transient network reset

A momentary network disruption between the runner and the host resets the connection. It is not deterministic.

How to fix it

Retry transient resets

Wrap the request in a bounded retry that treats ECONNRESET as retryable.

test/helpers.ts
async function withRetry(fn, tries = 3) {
  for (let i = 0; i < tries; i++) {
    try { return await fn(); }
    catch (e) { if (e.code !== 'ECONNRESET' || i === tries - 1) throw e; }
  }
}

Disable keep-alive reuse in tests

Use a fresh connection per test request so a stale keep-alive socket cannot be reset under you.

test/http.ts
const res = await fetch(url, { headers: { Connection: 'close' } });

How to prevent it

  • Add bounded retries for ECONNRESET in network-bound tests.
  • Avoid reusing keep-alive sockets across flaky test boundaries.
  • Isolate real-network tests so resets do not fail unrelated suites.

Frequently asked questions

What causes ""read ECONNRESET""?
A server or proxy closed an idle keep-alive socket just as the client reused it, producing a reset mid-read. This is intermittent.
How do I fix "read ECONNRESET"?
Wrap the request in a bounded retry that treats ECONNRESET as retryable.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card