{"record":{"id":"07177b69e2ecd0c2","repo":"different-ai/openwork","slug":"mcp-oauth-too-many-requests","errorCode":"MCP_OAUTH_TOO_MANY_REQUESTS","errorMessage":"Wait for the provider rate limit to reset, then retry with bounded backoff.","messagePattern":"Wait for the provider rate limit to reset, then retry with bounded backoff\\.","errorType":"error_code","errorClass":"TooManyRequestsError","httpStatus":429,"severity":"warning","filePath":"ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts","lineNumber":1338,"sourceCode":"      actionOwner: \"provider_admin\",\n      operatorAction: \"Configure the authorization server to issue a token type supported by the MCP client and resource.\",\n    }\n  }\n  if (name === \"MethodNotAllowedError\") {\n    return {\n      phase: fallbackPhase,\n      category: \"oauth_method_not_allowed\",\n      code: \"MCP_OAUTH_METHOD_NOT_ALLOWED\",\n      retryable: false,\n      actionOwner: \"provider_admin\",\n      operatorAction: \"Verify the provider OAuth endpoint path and its supported HTTP method.\",\n    }\n  }\n  if (name === \"TooManyRequestsError\") {\n    return {\n      phase: fallbackPhase,\n      category: \"oauth_provider_throttled\",\n      code: \"MCP_OAUTH_TOO_MANY_REQUESTS\",\n      retryable: true,\n      actionOwner: \"provider_admin\",\n      operatorAction: \"Wait for the provider rate limit to reset, then retry with bounded backoff.\",\n    }\n  }\n  if (name === \"AccessDeniedError\") {\n    return {\n      phase: \"AUTH_USER_OR_WORKLOAD\",\n      category: \"oauth_access_denied\",\n      code: \"MCP_OAUTH_ACCESS_DENIED\",\n      retryable: false,\n      actionOwner: \"member\",\n      operatorAction: \"Restart authorization and grant consent; if policy blocks consent, contact the provider administrator.\",\n    }\n  }\n  if (name === \"InvalidRequestError\" || name === \"UnsupportedGrantTypeError\" || name === \"UnsupportedResponseTypeError\") {\n    return {\n      phase: fallbackPhase,","sourceCodeStart":1320,"sourceCodeEnd":1356,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts#L1320-L1356","documentation":"This diagnostic code is emitted when the OAuth error name is TooManyRequestsError, i.e. the provider's authorization server returned HTTP 429 / a rate-limit error during the OAuth flow. The classifier marks it retryable (oauth_provider_throttled) but assigns the fix to the provider administrator, since the provider's limits control when retries will succeed.","triggerScenarios":"OAuth authorize/token/refresh calls to an external MCP provider exceed its request quota: repeated auth attempts in a loop, many concurrent users authenticating, refresh tokens being exchanged too frequently, or the provider throttling per-IP/per-client traffic during discovery.","commonSituations":"Shared egress IP (CI, proxy, office NAT) exhausting the provider's per-IP quota; an automated retry loop hammering the token endpoint without backoff; provider-side throttling recently tightened; burst of new MCP server connections after a deploy.","solutions":["Stop retrying immediately and wait for the provider rate-limit window to reset (check Retry-After if present).","Retry the OAuth flow with bounded exponential backoff and jitter instead of fixed tight loops.","Ask the provider admin to raise the rate limit or issue a dedicated client quota for your integration.","Reduce OAuth call frequency: cache tokens until near expiry and avoid redundant refreshes."],"exampleFix":"// before: fixed tight retry\nfor (;;) { await refresh(); }\n// after: bounded backoff honoring 429\nif (res.status === 429) { await sleep(Math.min(cap, base * 2 ** attempt) + jitter(attempt)); continue; }","handlingStrategy":"retry","validationCode":"const probe = await fetch(authorizeUrl, { method: 'HEAD' });\nif (probe.status === 429) throw new Error(`Provider throttled, retry after ${probe.headers.get('retry-after') ?? 'window reset'}`);","typeGuard":"function isTooManyRequests(e: unknown): boolean {\n  return typeof e === 'object' && e !== null && (e as { name?: string }).name === 'TooManyRequestsError';\n}","tryCatchPattern":"try { await startOAuth(server); } catch (e) {\n  if (isTooManyRequests(e)) { await backoffRetry(startOAuth, [server], { baseMs: 1000, capMs: 60000, maxAttempts: 5 }); return; }\n  throw e;\n}","preventionTips":["Cache OAuth tokens until near expiry; never refresh in a loop","Add jittered exponential backoff to every OAuth call","Pace bulk user onboarding to stay under per-IP/per-client quotas","Watch Retry-After headers and surface 429s instead of hot-retrying"],"tags":["oauth","rate-limit","http-429","retry"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}