different-ai/openwork · warning
MCP_HTTP_429
MCP_HTTP_429
Error message
MCP_HTTP_429
What it means
MCP_HTTP_429 is raised when the external MCP provider responds with HTTP 429 Too Many Requests. The classifier marks it provider_throttled, retryable, and owned by the provider admin: the request is valid but the provider's rate limit has been exhausted. The phase is preserved from the failing request so operators can see which lifecycle stage was throttled.
Source
Thrown at ee/apps/den-api/src/capability-sources/external-mcp-diagnostics.ts:929
actionOwner: "organization_admin",
operatorAction: "Verify the complete MCP endpoint path, including any provider tenant or instance prefix.",
}
}
if ((status === 406 || status === 415) && phase.startsWith("MCP_")) {
return {
phase: "MCP_TRANSPORT",
category: "mcp_transport_negotiation",
code: `MCP_HTTP_${status}`,
retryable: false,
actionOwner: "provider_admin",
operatorAction: "Verify Streamable HTTP content negotiation and the provider's supported MCP transport.",
}
}
if (status === 429) {
return {
phase,
category: "provider_throttled",
code: "MCP_HTTP_429",
retryable: true,
actionOwner: "provider_admin",
operatorAction: "Wait for the provider rate limit to reset, then retry with bounded backoff.",
}
}
if (status >= 500) {
return {
phase,
category: "provider_unavailable",
code: `MCP_HTTP_${status}`,
retryable: true,
actionOwner: "provider_admin",
operatorAction: "Check provider availability and reverse-proxy logs using the diagnostic reference, then retry.",
}
}
if ((status === 401 || status === 403) && phase.startsWith("MCP_") && input.hasAuthorization) {
// A 401 is itself an authentication challenge. A 403 is ambiguous for
// enterprise providers: only a Bearer/insufficient_scope challenge meansView on GitHub (pinned to 2b7df46e8a)
Solutions
- Wait for the provider rate-limit window to reset, then retry with bounded exponential backoff.
- Respect the Retry-After response header if the provider supplies one.
- Throttle or queue MCP tool calls in the caller, and consider requesting a higher quota from the provider admin.
Example fix
// before: immediate retry loop
for (;;) await callTool('search', args)
// after: bounded backoff honoring Retry-After
const delay = Number(res.headers.get('Retry-After') ?? 30) * 1000
await sleep(delay)
await callTool('search', args) Defensive patterns
Strategy: retry
Validate before calling
// simple client-side rate limiter to stay under provider limits
const limiter = new TokenBucket({ ratePerMin: 50 })
await limiter.take(1) // before each MCP call Type guard
function isThrottled(d: { code: string }): boolean {
return d.code === 'MCP_HTTP_429'
} Try / catch
for (let attempt = 0; attempt < 5; attempt++) {
try {
return await client.callTool(req)
} catch (e) {
if (!isThrottled(e.diagnostic)) throw e
const retryAfter = Number(e.headers?.['retry-after'] ?? 2 ** attempt)
await sleep(Math.min(retryAfter * 1000, 60_000)) // bounded backoff
}
}
throw new Error('rate limit persisted after retries') Prevention
- Instrument call volume per provider and keep it under documented quota.
- Use jittered exponential backoff with a max attempt count instead of tight loops.
- Batch or queue scheduled automations rather than polling in parallel.
When it happens
Trigger: Any MCP-phase HTTP request (tool discovery, tool execution, initialize) that the provider answers with status 429. Typically triggered by high tool-call frequency, large parallel batches, or shared per-tenant provider quotas being consumed by other workloads.
Common situations: Automations or scheduled agents hammering a tool in a tight loop; several agents in the same org sharing one provider API quota; bursty catalog pagination during tool discovery tripping per-minute limits.
Related errors
- MCP_PROVIDER_HTTP_429
- MCP_SESSION_NOT_FOUND
- MCP_LIFECYCLE_DEADLINE
- MCP_OAUTH_TOO_MANY_REQUESTS
- MCP_PROVIDER_INVALID_PARAMS|MCP_PROVIDER_HTTP_403|MCP_PROVIDER_HTTP_429
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/ffbad726541ee0fa.
Report an issue: GitHub.