{"record":{"id":"f4b008e2edab1caa","repo":"microsoft/playwright","slug":"failed-after-i-1-attempt-s-e","errorCode":null,"errorMessage":"Failed after ${i + 1} attempt(s): ${e}","messagePattern":"Failed after (.+?) attempt\\(s\\): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/fetch.ts","lineNumber":301,"sourceCode":"      setHeader(headers, 'cookie', valueArray.join('; '));\n    }\n  }\n\n  private async _sendRequestWithRetries(progress: Progress, url: URL, options: SendRequestOptions, postData?: Buffer, maxRetries?: number): Promise<SendRequestResult> {\n    const log: string[] = [];\n    maxRetries ??= 0;\n    let backoff = 250;\n    for (let i = 0; i <= maxRetries; i++) {\n      try {\n        return await this._sendRequest(progress, log, url, options, postData);\n      } catch (e) {\n        if (isAbortError(e))\n          throw e;\n        e = rewriteOpenSSLErrorIfNeeded(e);\n        if (maxRetries === 0)\n          throw e;\n        if (i === maxRetries)\n          throw new Error(`Failed after ${i + 1} attempt(s): ${e}`);\n        // Retry on connection reset only.\n        if (e.code !== 'ECONNRESET')\n          throw e;\n        const message = `  Received ECONNRESET, will retry after ${backoff}ms.`;\n        log.push(message);\n        progress.log(message);\n        await progress.wait(backoff);\n        backoff *= 2;\n      }\n    }\n    throw new Error('Unreachable');\n  }\n\n  private async _sendRequest(progress: Progress, log: string[], url: URL, options: SendRequestOptions, postData?: Buffer): Promise<SendRequestResult>{\n    const fetchLog = (message: string) => {\n      log.push(message);\n      progress.log(message);\n    };","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/fetch.ts#L283-L319","documentation":"Thrown by the internal retry loop after the request fails on every attempt. Retries only happen on ECONNRESET (connection reset by peer) and only when maxRetries > 0; once the loop reaches its final attempt it reports how many tries were made and the underlying error.","triggerScenarios":"Calling request.* with maxRetries set to N>0 while the target server or an intermediary load balancer actively resets the TCP connection (ECONNRESET) on every retry. The final message wraps the last ECONNRESET (or rewritten OpenSSL) error.","commonSituations":"Unstable upstream host behind a flaky proxy/load balancer; keep-alive connections closed server-side mid-request; TLS/SSL renegotiation resets; high-traffic endpoints that drop connections under load.","solutions":["Verify the endpoint is reachable and stable with a plain curl/node https request.","Check the server/proxy for connection-reset causes (idle timeouts, keep-alive settings, WAF).","Increase maxRetries only if resets are genuinely transient, otherwise lower it to surface failures faster.","Inspect the wrapped error in the message to see if it is an SSL/TLS issue and fix certificates accordingly."],"exampleFix":"// before\nawait request.get(url, { maxRetries: 3 }); // 3 ECONNRESETs -> throws\n// after: retry with backoff in your code AND validate reachability\nfor (let i = 0; i < 3; i++) {\n  try { return await request.get(url, { maxRetries: 0 }); }\n  catch (e) { if (i === 2) throw e; }\n}","handlingStrategy":"retry","validationCode":"// Reachability pre-check (cheap) before the real request\nconst net = require('net');\nconst ok = await new Promise(r => {\n  const s = net.connect(443, new URL(url).hostname).setTimeout(2000)\n    .on('connect', () => { s.destroy(); r(true); })\n    .on('error', () => r(false)).on('timeout', () => { s.destroy(); r(false); });\n});","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Monitor ECONNRESET rates on the target host; treat chronic resets as a server-side defect, not a client one.","Note: retries are ECONNRESET-only - other errors (DNS, TLS) will not retry."],"tags":["network","retry","econnreset"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}