Playwright Keep-Alive Issue Report: Protect Proxy API Tests from Socket-Reuse Resets

Bright data marbles move through fresh and aging Internet connection tubes around a proxy timing junction

An open issue filed in the Microsoft Playwright repository on September 13, 2026 reports that APIRequestContext can surface ECONNRESET when a pooled HTTP socket is reused near a server-advertised keep-alive timeout. The reporter reproduced failures around a six-second boundary under concurrent readers and observed that browser navigation did not expose the same symptom because Chromium retried a reused-socket failure.

This is a user report in an open issue, not a maintainer-confirmed defect or released fix. The reported environment used Playwright 1.58.2, Node 26.3.0, macOS arm64 and a Next.js development server. Teams should not assume every reset has this cause. They should use the report as a reason to preserve connection phase, test idle boundaries and make retries safe—especially when APIRequestContext runs through a proxy.

Internal research source: Microsoft Playwright repository, Issue 42698, “APIRequestContext ignores the server's Keep-Alive timeout, producing ECONNRESET on socket reuse,” opened September 13, 2026.

Why a proxy can make attribution harder

A proxied request has more reusable layers than a direct request. The client may reuse a connection to an HTTP proxy, a CONNECT tunnel may carry destination TLS, and the destination may enforce its own keep-alive timeout. SOCKS5 introduces another gateway path without changing the destination server's socket policy.

If a request fails on reuse, a generic “proxy error” hides whether the reset came from the client-to-gateway connection, the tunnel, the destination connection or the application response. Concurrency can widen timing races without being the root cause.

Reproduce the boundary with an owned fixture

Use a server you control that advertises a short keep-alive timeout. Return a random challenge and a server-side request identifier. Test direct and proxy paths with the same Playwright and Node versions.

Record:

test_id
route_alias
request_method
idempotency_key_hash
connection_sequence
idle_before_request_ms
proxy_session_mode
response_challenge
server_request_id_hash
failure_code
failure_phase
retry_count

Never store proxy passwords, cookies, authorization headers or raw idempotency keys.

Sweep idle intervals below, around and above the advertised timeout. For a six-second close boundary, a compact matrix might include 4.5, 5.0, 5.5, 5.9, 6.0, 6.1, 6.5 and 7.0 seconds. Use several repetitions per interval, first with one worker and then with limited concurrency.

Separate direct, proxy and browser controls

ControlPurpose
Direct APIRequestContextEstablish whether the API client shows the reset without a proxy
Proxied APIRequestContextMeasure gateway and tunnel effects
Browser navigationCheck whether browser-level retry masks the reset
Fresh request contextCompare a new pool with reused sockets
Connection-close controlVerify that avoiding reuse changes the symptom

Do not set Connection: close globally in a mixed browser/API context without measuring collateral effects. It may reduce reuse for navigations and assets that were not failing.

Retry only when the operation is safe

The issue reporter proposed retrying idempotent verbs on ECONNRESET and deliberately excluded POST because the server may already have processed a create before the client reads the reset. That distinction is critical for data collection and account workflows.

Classify operations before adding retries:

  • Usually safe with bounded retry: a read-only GET with no server-side mutation;
  • Safe only with a verified key: PUT, PATCH or DELETE protected by server-enforced idempotency and a result lookup;
  • Unsafe by default: POST, purchase, registration, message send or any operation whose first outcome cannot be proven;
  • Stop immediately: authentication, permission or policy failures.

Even a nominally idempotent method may trigger application side effects. Verify behavior at the owned server, not only by method name.

Use an outcome ledger

Before retrying a mutation, store a hashed operation identifier and check the server-side result. The ledger should distinguish:

  1. not sent;
  2. sent, no response observed;
  3. server accepted;
  4. server rejected;
  5. duplicate prevented;
  6. final outcome unknown.

An unknown outcome should enter reconciliation, not blind replay. This prevents a read-side reset from creating duplicate records or orders.

Test proxy session behavior separately

A retry may reuse the same proxy connection, open a new tunnel, or select a new rotating exit. Record which occurred. If the destination binds state to source IP, changing the exit during a retry can alter the result even when the HTTP method is safe.

Use the session stickiness test to verify route identity, and the connection pooling guide to define pool ownership. Keep retry load below the limits established in the concurrency saturation test.

Diagnose without blaming the wrong layer

When a reset appears:

  1. confirm whether the socket was fresh or reused;
  2. compare the idle duration with the server timeout;
  3. check whether the server received and completed the operation;
  4. repeat without the proxy;
  5. repeat with a new request context;
  6. compare browser navigation and API context behavior;
  7. test another gateway without changing the destination;
  8. inspect bounded client and server timing logs.

Avoid packet capture on third-party traffic. If deeper capture is necessary, use a lab fixture with approval and minimize payload retention.

Release checklist

  • The issue is tracked as an open report, not a confirmed release note.
  • Direct and proxied idle-boundary tests are complete.
  • Fresh and reused sockets are distinguishable.
  • Server receipt is correlated with client outcome.
  • Retried operations have an explicit safety classification.
  • Mutation retries require idempotency and reconciliation.
  • Retry count and total elapsed time are bounded.
  • Proxy session changes are recorded.
  • Logs contain no credentials or personal data.
  • A rollback or connection-pool mitigation is tested.

FAQ

Does every ECONNRESET indicate this reported issue?

No. Gateways, destinations, local networks, TLS shutdown and application processes can all reset connections. Reproduce the idle boundary before attributing cause.

Should we retry every reset once?

No. A mutation may already have succeeded. Retry only when the operation is proven safe or protected by server-enforced idempotency and reconciliation.

Why might browser navigation look healthy?

The report states that Chromium retried the reused-socket failure in its test, while APIRequestContext surfaced it. Confirm this in your own version and environment.

Is disabling keep-alive a permanent fix?

It can be a diagnostic or temporary mitigation, but it increases connection setup and may affect browsers if applied broadly. Measure scope and cost before rollout.

Compliance note

Reproduce only on systems and proxy routes you own or are authorized to test. Respect platform rules, contracts, rate limits and privacy requirements. Do not retry purchases, registrations or other consequential actions without explicit idempotency protection and outcome reconciliation.