ExplainerOct 24, 20267 min read

Three 429s, three meanings: OpenAI, Anthropic and Gemini

The same status code means “slow down” at one provider and “pay your bill” at another. Here is how to tell them apart in one catch block.

If your LLM wrapper retries every 429, it is wrong at least once a month. Each provider uses the status for different things, and only the body tells you which.

OpenAI: read error.code

rate_limit_exceeded is a per-minute limit and clears in seconds. insufficient_quota arrives as the same 429 RateLimitError, but means the project is out of credit. Retrying it just loops.

insufficient_quotaCriticalYou exceeded your current quotaSame 429 status as a rate limit, but the cause is billing: the project has no credit left or hit its monthly budget. Retrying never helps; add credits or raise the budget.

Anthropic: 429 is yours, 529 is theirs

rate_limit_error (429) means your organization’s limits; honour retry-after. overloaded_error (529) means the provider is short on capacity, so retry or fall back to another model.

overloaded_errorWarning↻ retryableAPI temporarily overloaded (529)Anthropic’s API is briefly out of capacity across all users; your request and your limits are fine. Retry with exponential backoff, and fall back to another model if it persists.

Gemini: RESOURCE_EXHAUSTED covers both windows

Per-minute and per-day quotas share the same RESOURCE_EXHAUSTED status. If backoff stops working after a few minutes, you have probably hit the daily cap.

RESOURCE_EXHAUSTEDWarning↻ retryableQuota exceeded (429)You hit a Gemini API limit: requests per minute, tokens per minute or requests per day for this model and tier. Back off and retry for per-minute limits; per-day limits need billing or a higher tier.

One classifier for all three

classify.ts
export function classify(provider, status, body) {
  if (provider === "openai" && body?.error?.code === "insufficient_quota") return "billing";
  if (provider === "anthropic" && status === 529) return "provider-overload";
  if (status === 429) return "rate-limit";
  if (status >= 500) return "provider-error";
  return "fix-request";
}
// billing → page a human · rate-limit → backoff · provider-overload → retry, then fall back
Tip

Track the three classes as separate metrics. A rising billing count is a finance problem; a rising overload count is a reason to add a second provider.