Insights
SRE3 September 2026

Claude and OpenAI went down on the same afternoon. Here is what I changed in my own code.

Two providers degraded for the same 85 minutes. One endpoint and one key is not a plan. Here is the fallback chain I built while waiting.

What I saw

At about half past two on the afternoon of 3 September my coding agent stopped doing anything useful. Every request came back as HTTP 529 and the client sat there retrying: "Model overloaded. Retrying (4/10). 1m 38s." I did what most people do and reached for the other vendor's tool to keep working. It returned 404 twice.

What I actually saw

The status pages filled in the rest later. Anthropic had an incident titled "Elevated errors for multiple models" from roughly 13:41 UTC to 16:23, and its 90-day history later marked the day as a partial outage of 3 hours 6 minutes. OpenAI had "Elevated errors across ChatGPT and Codex" from 14:58 to 16:55. The overlap was about 85 minutes.

OpenAI status page that evening: 90-day bars, ChatGPT 99.63 percentClaude status page that evening: red bars on Today, incident resolved 16:23 UTC

That is not rare enough to ignore. In November 2025 a Cloudflare configuration change took ChatGPT and Claude offline together for about four hours, because both sit behind the same edge network. And the 90-day figures on the two status pages that evening read 99.5 percent for the Claude API, 99.44 percent for Claude Code, 99.63 percent for ChatGPT and 99.94 percent for OpenAI's APIs. Half a percent of a quarter is about eleven hours. Assume this will happen during work you care about, on a schedule you do not control.

What a 529 actually is

Anthropic's docs define it plainly: "529 overloaded_error: The API is temporarily overloaded", and it "can occur when the API experiences high traffic across all users". It is not about you. A 429 is about you: your rate limit, your spend cap. The docs add a detail that matters for retry code. Not every 429 is a rate limit. Some mean your account has hit the monthly spending limit you set in the console. That kind of 429 comes with no Retry-After header and keeps failing until the limit resets or you raise it. Retrying it is pure waste. Two failures can wear the same status code and still need opposite responses. Read the error body, not just the number.

Two more things from the same page that most retry loops get wrong. Anthropic's official SDKs already retry transient failures twice by default, honouring Retry-After, so a retry loop wrapped around the SDK multiplies the wait. And on streaming responses an error can turn up after the 200, mid-stream, so your streaming path has to handle errors too.

My own code was worse than the tools I was cursing

I run a small pipeline of my own that uses a model to triage a daily feed of documents. While I was annoyed at the agent for retrying, I opened my own client. One base URL. One API key. It retried once, only on 429, after a fixed 15 second sleep. Nothing for 5xx, nothing for 529, no second provider, no breaker. If that endpoint had been the one having the afternoon, my pipeline would have quietly produced nothing.

So I spent the outage fixing it. The shape now:

A fallback chain with a floor

I made the control flow explicit. Classify the error, retry only the retryable cases with backoff that is capped and randomised a little so a thousand clients do not retry in lockstep, and honour Retry-After. Put a circuit breaker in front of each provider: after a few failures in a row, stop calling it for a couple of minutes instead of hammering it, the same job the breaker in your fuse box does. Try the next provider, then the local model. If nobody answers, mark the work as deferred so the rest of the pipeline keeps running without the AI step. In pseudocode:

for provider in [primary, second_vendor, local_model]:

    if provider.breaker_is_open():        # tripped by 3 failures in the last minute
        continue

    for attempt in 1..3:
        response = provider.call(request)

        if response.ok:
            return response

        if response.status == 429 and response.mentions_spending_limit:
            provider.trip_breaker()       # no retry fixes this one
            break

        if response.is_retryable:         # 429 with Retry-After, 5xx, 529, timeout
            sleep(response.retry_after or backoff_with_jitter(attempt))
            continue

        provider.trip_breaker()           # any other 4xx is our bug, not theirs
        break

return DEFER                              # nobody answered: skip the AI step, carry on

The providers come from environment variables, all speaking the OpenAI-compatible chat format: the primary, an optional second vendor, and an optional local model served by Ollama at `http://localhost:11434/v1`. The local one is slow and worse. It also answers when nobody else does, which is the whole point of a floor.

You do not have to write this yourself. LiteLLM's router does retries, fallbacks and cooldowns as configuration: by default a provider that fails three times in a minute is rested for a few seconds, and you list fallback models in order. OpenRouter does the failover on the gateway side, dropping a provider to the back of the queue after a 30 second window of errors, and their own advice is to put the most reliable model last as the floor. One caveat with any gateway: it is another thing that can go down. OpenRouter's did, for about 50 minutes, in August 2025.

After the outage, I had the recovered model sanity-check the list below. It caught two mistakes I had missed.

The fix, in the order that pays

The pseudocode covers the first four: classify the error, retry only what is retryable, a breaker per provider, a chain that ends in something you control. The rest of the list is what the pseudocode does not show.

  • Degrade by feature, not by product. My pipeline skips the AI step and still delivers its daily output. Yours might serve a cached answer, a template, or a queue.
  • Make anything with side effects safe to retry, which is what idempotent means. A retried request that already succeeded on the far side sends the email twice.
  • Alert on your own error rate and defer rate. The vendor status page lagged my 529s by over an hour that afternoon.
  • Test your prompts against the backup model before you need it. A fallback that answers in a different JSON shape, or refuses things the primary did not, is a quality problem with no alarm on it.
  • A kill switch per AI feature. Turn off the summariser without turning off the product.
  • Spend caps on the fallback. You just doubled your surface at a moment of maximum traffic.

Mistakes I have seen, and one I made

Retrying every 429, including the ones that mean you have hit your own monthly spending limit, which no amount of retrying fixes. Stacking application retries on SDK retries on gateway retries until one request takes four minutes. Assuming prompts are portable and finding out during the incident that the backup model calls tools differently. Failing all traffic over to a backup account nobody has ever sent a request through. And mine: believing my own client was fine because it had a retry in it. It had one retry, for one status code, with a fixed sleep. That is a comment, not a policy.

Key takeaways

  • Both major providers were degraded at the same time for about 85 minutes. Multi-vendor helps, but it is not enough on its own.
  • Read the error before retrying it. 529 is them, 429 is you, and a 429 caused by your own spending limit never gets better on its own.
  • Put a circuit breaker in front of each provider, and end the chain with something you control, even if that is "skip this step and carry on".
  • Check your own client now, not after the next incident. Mine was worse than the tools I was complaining about.

Sources

  • Anthropic API errors reference: https://platform.claude.com/docs/en/api/errors
  • Anthropic status, incident "Elevated errors for multiple models", 3 Sep 2026: https://status.claude.com
  • OpenAI status, incident "Elevated errors across ChatGPT and Codex", 3 Sep 2026: https://status.openai.com/incidents/01M1KWEDH417T2CF44YYHZDFCR
  • Cloudflare outage of 18 Nov 2025 taking ChatGPT and Claude offline: https://siliconangle.com/2025/11/18/cloudflare-outage-briefly-takes-chatgpt-claude-services-offline/
  • LiteLLM router (fallbacks, cooldowns, retries): https://docs.litellm.ai/docs/routing
  • OpenRouter on provider failover vs model fallbacks: https://openrouter.ai/blog/insights/reliability-failover/
ShareLinkedIn

Get the next one in your inbox

One short, opinionated field note per fortnight on platform engineering, cloud, and making AI work in production. No spam. Unsubscribe anytime.

Senna Semakula

Senna Semakula

Founder, Atruvo

Bring your architecture diagram, cloud bill, or last incident summary.

I will tell you what is actually breaking.

30 minutes. No pitch. Ranked risks and a clear next step.