{"record":{"id":"40e0796df4f2394f","repo":"n8n-io/n8n","slug":"estatus","errorCode":"ESTATUS","errorMessage":"HTTP status ${status}","messagePattern":"HTTP status (.+?)","errorType":"exception","errorClass":"ResponseError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/client-oauth2/src/client-oauth2.ts","lineNumber":165,"sourceCode":"\t\tif (options.ignoreSSLIssues || lookup) {\n\t\t\trequestConfig.httpsAgent = createHttpsProxyAgent(url, undefined, {\n\t\t\t\t...(options.ignoreSSLIssues ? { rejectUnauthorized: false } : {}),\n\t\t\t\t...(lookup ? { lookup } : {}),\n\t\t\t});\n\t\t}\n\n\t\tif (lookup) {\n\t\t\trequestConfig.httpAgent = createHttpProxyAgent(url, undefined, { lookup });\n\t\t}\n\n\t\tconst response = await axios.request(requestConfig);\n\n\t\tif (response.status >= 400) {\n\t\t\tconst body = this.parseResponseBody<OAuth2AccessTokenErrorResponse>(response);\n\t\t\tconst authErr = getAuthError(body);\n\n\t\t\tif (authErr) throw authErr;\n\t\t\telse throw new ResponseError(response.status, response.data);\n\t\t}\n\n\t\tif (response.status >= 300) {\n\t\t\tthrow new ResponseError(response.status, response.data);\n\t\t}\n\n\t\treturn this.parseResponseBody<ClientOAuth2TokenData>(response);\n\t}\n\n\t/**\n\t * Attempt to parse response body based on the content type.\n\t */\n\tprivate parseResponseBody<T extends object>(response: AxiosResponse<unknown>): T {\n\t\tconst contentType = (response.headers['content-type'] as string) ?? '';\n\t\tconst body = response.data as string;\n\n\t\tif (contentType.startsWith('application/x-www-form-urlencoded')) {\n\t\t\treturn qs.parse(body) as T;","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/client-oauth2/src/client-oauth2.ts#L147-L183","documentation":"ResponseError (code ESTATUS) thrown by ClientOAuth2.accessTokenRequest when the token endpoint returns status >= 400 (after getAuthError finds no standard OAuth2 error body) or status >= 300. It carries the HTTP status and raw response data; ESTATUS is the library's stable code for 'unexpected token endpoint status'.","triggerScenarios":"axios.request to the OAuth2 accessTokenUri returns a non-3xx-non-2xx status. If the body parses to a standard OAuth2 error (invalid_grant, invalid_client, etc.) getAuthError throws that instead; otherwise this generic ResponseError is thrown. 3xx (unsupported redirect on a POST token endpoint) also triggers it.","commonSituations":"invalid_client (wrong client_id/secret); the token endpoint URL is wrong and returns an HTML 404; a provider returns a non-standard error body; network middleware returns a 502/504 on the token endpoint; an expired authorization code being exchanged late.","solutions":["Read the embedded status: 401 -> invalid_client (check id/secret), 400 -> invalid_grant (re-auth), 5xx -> provider issue.","Inspect the response data on the ResponseError for provider-specific error text.","Verify the accessTokenUri is correct and not behind a redirect.","Ensure the client_id, client_secret, scopes, and redirect_uri match the provider app registration."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm the token endpoint is reachable and returns 2xx for a known request\n// (operational smoke check, not in-process)","typeGuard":"import { ResponseError } from './client-oauth2';\nconst isOAuthStatusError = (e: unknown): boolean =>\n  e instanceof ResponseError && (e as any).code === 'ESTATUS';","tryCatchPattern":"try {\n  return await client.accessTokenRequest(requestOptions);\n} catch (e) {\n  if (e instanceof ResponseError && e.status === 401) {\n    // invalid_client — fix id/secret\n  } else if (e instanceof ResponseError && e.status === 400) {\n    // invalid_grant — re-authorize\n  } else if (e instanceof ResponseError && e.status >= 500) {\n    // retry token endpoint with backoff\n  } else {\n    throw e;\n  }\n}","preventionTips":["Match client_id, client_secret, scopes, and redirect_uri exactly to the provider registration.","Do not redirect the token endpoint (POST must return 2xx directly).","Handle getAuthError's typed OAuth2 errors (invalid_grant, invalid_client) before falling back to ResponseError."],"tags":["oauth2","auth","http-status","token-endpoint","client-oauth2"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}