DEV Community

Cover image for Your Claude Integration Will Go Down. Here Is How to Fail Over Cleanly
Alessandro Pignati
Alessandro Pignati

Posted on

Your Claude Integration Will Go Down. Here Is How to Fail Over Cleanly

Triage the error in 60 seconds, then build a fallback chain that keeps your app and agents running when Anthropic has a bad morning.

On September 3, 2026, ChatGPT, Claude and Grok all had outages on the same morning. The Register reported that Claude's status page logged roughly three hours of elevated errors across claude.ai, Claude Code, Cowork and the API. No shared root cause was confirmed. If your plan B was "switch to the other big provider," that morning showed why it is not a plan.

This post is the developer version of NeuralTrust's longer guide, Is Claude Down? Status, Fixes & Fallback. It skips the consumer advice and focuses on two things: figuring out fast whether the problem is yours or Anthropic's, and designing a fallback that actually works when it is Anthropic's.

Step 1: Is it Claude, or is it you?

Start at status.claude.com. Anthropic lists claude.ai, the Console, the API, Claude Code and other surfaces as separate components, and many incidents only hit specific models. Read the incident text, not just the colors. A partial incident on one model family can look like a total outage from inside your app.

If everything is green, assume the problem is on your side until proven otherwise. Your key, your billing, your rate limits and your network are all more likely culprits than a silent global outage.

Step 2: Let the status code do the triage

The Claude API returns a typed error body that looks like this:

{
  "type": "error",
  "error": {
    "type": "overloaded_error",
    "message": "..."
  },
  "request_id": "req_..."
}
Enter fullscreen mode Exit fullscreen mode

According to Anthropic's API errors reference, the codes split cleanly by ownership.

Anthropic's problem (retry, then fail over):

  • 529 overloaded_error. The API is temporarily overloaded, typically under high traffic across all users.
  • 500 api_error. Something broke inside Anthropic. Retry with exponential backoff. If it persists, contact support with the request ID.
  • 504 timeout_error. The request timed out while processing. This one is partly on you. Long generations should use streaming or the Message Batches API instead of a single blocking call.

Your problem (do not fail over, fix it):

  • 400 invalid_request_error. Malformed request. Note that hitting an organization or workspace spend limit you configured also returns a 400.
  • 401 authentication_error / 403 permission_error. Bad, expired or under-scoped key.
  • 402 billing_error. Payment issue on the account.
  • 429 rate_limit_error. Usually a rate limit, which carries a retry-after header. But a 429 caused by your usage tier's monthly spend cap has no retry-after header and keeps failing until access resumes. Retrying that forever looks exactly like an outage in your logs. It is not one.

Two details matter here. First, the official SDKs already retry connection errors, 429s and 5xx responses twice by default with exponential backoff (configurable with max_retries). By the time an error reaches your code, it has usually failed three times. Second, always log request_id. It is the only thing support can act on.

Step 3: Design the fallback in levels

The original article frames fallback as three levels, ordered by how much they change your app's behavior.

Level 1: Same Claude model, different cloud. Claude models are also served through Amazon Bedrock, Google Cloud and Microsoft Foundry. This is the cleanest fallback because the model is the same, so prompts, tool schemas and evals carry over. It is also the only kind of fallback that makes sense for Claude Code, since Anthropic does not support routing Claude Code to non-Claude models through a gateway (per Anthropic's Claude Code gateway documentation).

Level 2: Different Anthropic model. If one model family is degraded and another is healthy, dropping to a different tier keeps you inside the same API and the same prompt conventions. Quality and latency will shift, so this is a degrade path, not a transparent swap.

Level 3: Different vendor. This is the only level that survives a full Anthropic outage. It is also the one that breaks things. Different tokenizers, different tool-calling formats, different refusal behavior. Treat it as a separate deployment target with its own eval suite, not as a config flag you flip during an incident.

A minimal Level 1 fallback in Python

Here is the core logic, stripped down. It only fails over on errors that are Anthropic's to fix, and it refuses to fail over on a spend-cap 429.

import anthropic
from anthropic import Anthropic, AnthropicBedrock

primary = Anthropic(max_retries=2)
fallback = AnthropicBedrock(aws_region="us-east-1", max_retries=1)

# Model IDs differ per provider. Map them explicitly.
MODEL_MAP = {
    "primary": "<anthropic-model-id>",
    "fallback": "<bedrock-model-id>",
}

FAILOVER_STATUSES = {500, 504, 529}


def should_fail_over(err: Exception) -> bool:
    if isinstance(err, anthropic.APIConnectionError):
        return True
    if isinstance(err, anthropic.APIStatusError):
        if err.status_code in FAILOVER_STATUSES:
            return True
        if err.status_code == 429:
            # Spend-cap 429s have no retry-after header. Failing over
            # just moves the bill. Surface it instead.
            return err.response.headers.get("retry-after") is not None
    return False


def create_message(messages, max_tokens=1024):
    try:
        return primary.messages.create(
            model=MODEL_MAP["primary"],
            max_tokens=max_tokens,
            messages=messages,
        )
    except Exception as err:
        if not should_fail_over(err):
            raise
        request_id = getattr(err, "request_id", None)
        print(f"Primary failed ({err.__class__.__name__}, {request_id}), using fallback")
        return fallback.messages.create(
            model=MODEL_MAP["fallback"],
            max_tokens=max_tokens,
            messages=messages,
        )
Enter fullscreen mode Exit fullscreen mode

This works for one service. It stops scaling once you have a dozen services, several teams and a mix of chat apps, agents and Claude Code users, because every one of them reimplements the same chain slightly differently.

Move the chain into a gateway

The more durable pattern is to put fallback in an LLM gateway so clients call one endpoint and the gateway owns the provider chain. NeuralTrust's TrustGate routing docs describe the model clearly:

  • Fallback is an ordered chain of registries. The gateway tries the first, and moves to the next only when a failure matches a configured trigger.
  • Triggers include HTTP 5xx, HTTP 429, timeouts, provider-reported errors and policy rejections.
  • A budget caps the damage: a maximum number of attempts and a maximum total latency across all attempts. When the budget runs out, the client gets the last real error, not a synthesized one.
  • A failed registry is never retried within the same request.

Two design notes from those docs are worth stealing even if you build your own. The same model name has to resolve on every registry in the chain, or fallback stops there. And triggers should match intent. Rate-limit triggers make sense for a cross-provider resilience chain. Policy-rejection triggers usually do not, because a request blocked by policy on one provider should not quietly retry somewhere else.

For Claude Code, the integration point is ANTHROPIC_BASE_URL. Point it at the gateway, issue developers gateway credentials, and admins can pin that endpoint through managed settings so sessions cannot bypass it. NeuralTrust's Agent Gateway is built for this, sitting in front of model providers, MCP servers and agent-to-agent traffic as one control point.

The pitfalls nobody tests until the outage

  • Model name drift. Every provider uses its own model IDs. Keep one mapping table and test it in CI, not during an incident.
  • Cost surprises. Per-token pricing differs across clouds and across tiers. A fallback that runs for three hours at a higher rate shows up on next month's bill.
  • Data terms. Your fallback provider may have different retention and data processing terms than your primary. Legal approval for one does not cover the other.
  • Untested Level 3. If the vendor fallback has never run your eval suite, it is not a fallback. It is a guess.

Failover is also a security event

Outages create pressure to "just get it working," and that is when controls slip. The fallback path needs the same guardrails as the primary: the same prompt injection screening, the same PII handling, the same logging and the same alerting. If your primary path is protected and your fallback path is a raw API key in an environment variable, an attacker only needs to wait for the next incident.

There is also a human side. When the approved tool is down, people reach for unapproved ones and paste in whatever they were working on. A gateway that keeps working through an outage is partly a shadow AI control.

If you run autonomous agents on top of Claude, this gets sharper, because agents keep taking actions while you are firefighting. AgentSecurity.com collects threat models and controls specific to agentic systems, including tool abuse and privilege escalation, which are worth reviewing alongside your failover design.

Quick checklist

  1. Check status.claude.com and read the component and model, not just the color.
  2. Use the status code to decide ownership. 5xx and 529 are Anthropic's. 4xx is yours. A 429 without retry-after is your spend cap.
  3. Log request_id on every error.
  4. Build fallback in levels: same model on another cloud, then another Claude model, then another vendor with its own evals.
  5. Centralize the chain in a gateway with explicit triggers and a retry budget.
  6. Give the fallback path the same security controls as the primary.

The next outage is a when, not an if. The teams that barely notice it are the ones that rehearsed the failover on a quiet Tuesday.

Top comments (0)