
529 overloaded_error: Retrying Without Making It Worse
Figures on this page were verified 31 August 2026 against the providers' own documentation. Pricing, context windows and rate limits change without notice, so confirm any number against the provider before you rely on it. Tell us if something here is out of date.
A 529 is not your fault and there is nothing in your request to fix. It means Anthropic’s API is temporarily saturated and is shedding load. Unlike a 400 or a 401, this one is genuinely retryable: back off, add jitter, try again. The only real work is making sure your client degrades gracefully instead of collapsing.
Know which failures are yours
Server-side errors get lumped together and handled badly. This table is the whole decision:
| Status | Meaning | Cause | Retry? |
|---|---|---|---|
| 429 | Rate limited | You, or your billing | Yes, unless it is a quota error |
| 500 | Internal server error | Provider | Yes, cautiously |
| 503 | Service unavailable | Provider | Yes |
| 529 | overloaded_error, API saturated | Provider | Yes |
| 400 | Malformed request | You | Never |
| 401 | Authentication | You | Never |
529 is Anthropic-specific. OpenAI expresses the same condition as a 503. If you are writing provider-agnostic code, treat 429 (non-quota), 500, 503 and 529 as one retryable family and everything in the 4xx range except 429 as terminal.
Retry without making it worse
An overloaded service is the one situation where aggressive retries actively harm you. Every client hammering at a fixed interval adds load to a system already shedding it, and they all return at the same instant because they all failed at the same instant. Jitter is not a nicety here, it is the mechanism that breaks the synchronisation.
import random, time
import anthropic
client = anthropic.Anthropic()
RETRYABLE = (
anthropic.APIStatusError, # covers 500 / 503 / 529
anthropic.APIConnectionError, # network-level
)
def call(fn, attempts=5):
for i in range(attempts):
try:
return fn()
except anthropic.RateLimitError:
raise # handle 429 separately
except RETRYABLE as e:
status = getattr(e, "status_code", None)
if status is not None and status < 500:
raise # 4xx is terminal, do not loop
if i == attempts - 1:
raise
time.sleep((2 ** i) + random.uniform(0, 1))Note the guard on status < 500. APIStatusError is a broad parent class, and catching it without checking the code will happily retry a malformed request forever.
Cap the total, not just the attempts
Five attempts with exponential backoff is up to 31 seconds of sleeping before the final failure, plus the request time. Inside a web request that is well past the point where the user has left. Decide your total time budget first, then derive the attempt count from it, rather than picking a number of retries and discovering the latency afterwards.
Official SDKs already retry connection errors and 5xx a couple of times by default. If you add your own wrapper on top without lowering max_retries, you get the product of the two, not the sum.
Design so saturation is survivable
- Make the work asynchronous. A queued job can afford to wait minutes. A blocking HTTP handler cannot. Moving generation off the request path removes the entire class of problem.
- Use batch endpoints for offline work. They are built for throughput rather than latency and are not competing for the same synchronous capacity.
- Have a fallback path. A smaller or alternative model that returns something beats a spinner that returns nothing. Decide in advance whether degraded output is better than no output for your use case.
- Add a circuit breaker. After repeated 529s, stop trying for a while and fail fast. Continuing to queue work against a saturated service just moves the outage into your own system.
- Stream long responses. Partial output already delivered is not lost when a later call fails.
When it is not transient
Sustained 529s across many minutes are an incident, not a blip. Check the provider’s status page before spending an afternoon instrumenting your retry logic. If your own dashboards show a clean spike starting at a round time and affecting every request equally, the cause is very unlikely to be in your code.
Log the status code and a request identifier on every failure. Without them you cannot tell a provider incident from a bug you shipped, and that distinction is the whole of the debugging.
Related
For the 429 case, which is the one error that is sometimes yours and sometimes billing, see 429 rate limit and quota errors. For failures that no retry will ever fix, see invalid API key and context_length_exceeded.
This page is part of our LLM API error reference, which covers every common error across OpenAI and Anthropic and whether each one is safe to retry.
Frequently asked questions
Does a 529 mean I did something wrong?
No. 529 overloaded_error is Anthropic signalling that its own capacity is saturated. Your request was well formed and would likely succeed moments later, which makes it one of the clearest cases for an automatic retry.
How do I retry a 529 without making the problem worse?
Exponential backoff with full jitter, never a fixed sleep. When many clients all wait the same interval they retry in lockstep and recreate the spike that caused the saturation. Cap the number of attempts and fail loudly rather than retrying indefinitely.
How should a system be designed for provider saturation?
Queue the work instead of calling the API synchronously from a request path, degrade to a smaller or alternative model when the primary is unavailable, cache aggressively, and make every user-facing operation idempotent so that a retry is always safe.


