Errors and Retries

Common Errors

HTTP codeSDK exceptionCauseRetry?
400BadRequestErrorWrong parameters (e.g. missing max_tokens, unsupported setting)No, fix the request
401AuthenticationErrorMissing or invalid API keyNo
404NotFoundErrorWrong model IDNo
429RateLimitErrorToo many requests or tokens per minuteYes, after waiting
500 / 529InternalServerError / overloadedProvider-side problemYes, with backoff
—APIConnectionErrorNetwork problemYes

The SDK already retries 429, 5xx and connection errors twice with exponential backoff. Change it with anthropic.Anthropic(max_retries=5).

Catching Errors

import anthropic

client = anthropic.Anthropic(max_retries=3, timeout=30.0)

try:
    response = client.messages.create(
        model="claude-sonnet-5-5",
        max_tokens=300,
        messages=[{"role": "user", "content": "Hi"}],
    )
except anthropic.AuthenticationError:
    print("Check ANTHROPIC_API_KEY")
except anthropic.RateLimitError:
    print("Too many requests - try again shortly")
except anthropic.APIStatusError as e:
    print(f"API error {e.status_code}: {e.message}")
except anthropic.APIConnectionError:
    print("Network problem")

How Exponential Backoff Works

Example

Retry logic waits 1s, 2s, 4s, ... between attempts so a busy server gets breathing room. A fake flaky function stands in for the API, and the waits are only printed (real code calls time.sleep):

class RateLimitError(Exception):
    pass

attempts = {"n": 0}
def flaky_api():
    attempts["n"] += 1
    if attempts["n"] <= 3:
        raise RateLimitError("429 rate_limit_error")
    return "Your order SE-10423 is out for delivery."

def call_with_retry(fn, max_retries=5, base_delay=1.0, max_delay=30.0):
    for attempt in range(max_retries + 1):
        try:
            return fn()
        except RateLimitError as e:
            if attempt == max_retries:
                raise
            delay = min(base_delay * 2 ** attempt, max_delay)
            print(f"attempt {attempt + 1}: {e} -> wait {delay:.0f}s")
            # time.sleep(delay)

print("result:", call_with_retry(flaky_api))

Output

attempt 1: 429 rate_limit_error -> wait 1s
attempt 2: 429 rate_limit_error -> wait 2s
attempt 3: 429 rate_limit_error -> wait 4s
result: Your order SE-10423 is out for delivery.

Tip: Real retry code also adds a little random jitter to each delay so thousands of clients do not retry at the same moment. Never retry 400/401 errors: they will fail again.