DEV Community

Owen
Owen

Posted on • Originally published at ofox.ai

Claude Code fallbackModel: 3-Tier Failover Setup (2026)

Claude Code fallbackModel retries up to 3 models on a 529 overload, not on 429. Set it up in 4 steps (settings.json + CLI) and know when a gateway wins.

Set Up 3-Tier Failover in 4 Steps

When Anthropic returns a 529 overloaded_error, an unconfigured Claude Code session retries the same model, then hands you the error. A fallback chain turns that dead end into a downshift: overloaded on Opus, retry on Sonnet, and if that is also unavailable, Haiku.

What you can do

Keep a turn alive through a 529 overload by having Claude Code try up to three backup models in order

Time required

About 5 minutes

What you need

Claude Code v2.1.197+ (for the Sonnet 5 alias), account access to the models you list, and edit access to a settings.json

The whole configuration is one array:

{
  "model": "opus",
  "fallbackModel": ["sonnet", "haiku"]
}
Enter fullscreen mode Exit fullscreen mode

That is a three-tier chain: opus is the primary, sonnet and haiku are the fallbacks. The rest of this guide is about the parts that are not obvious from the array: which errors actually trigger it, why a 429 does not, how the chain behaves across a team, and where a single-account chain stops helping.

What You Can Do After This Setup (And What You Can't)

A fallback chain is a narrow tool. It is worth being precise about its edges before you build one, because the failure it fixes looks a lot like two failures it does not.

Here is what a fallback chain does for you:

  • Survives a transient Anthropic overload (529 overloaded_error) without losing the turn.
  • Keeps working when a specific model is unavailable, for example a model pinned in settings that has since been retired.
  • Downshifts capability deliberately, so a hard task that starts on Opus finishes on Sonnet rather than not at all.

Here is what it will not do:

  • Get you past a 429 rate limit or a usage cap. Those are quota problems, and every model in the chain draws from the same account quota.
  • Fail over to a different provider. Chain elements resolve to Claude models on one account, so a total Anthropic outage takes the chain down with it.
  • Change your primary model permanently. A switch is per-turn, and the next message starts on your primary again.

If your recurring pain is "usage limit reached" rather than "overloaded," a fallback chain is the wrong fix. See the separate guide on rate limit reached in Claude Code, and for the API-level version of the overload itself, Claude API error 529.

Decision Frame: When to Use This Setup (and When NOT)

When to use it

  • You run Claude Code in an unattended or scripted context (CI, a long agent run, an overnight task) where a mid-turn 529 would otherwise abort the whole job.
  • You are on a paid API or high tier where overloads, not quota, are your usual interruption.
  • You can tolerate a quality downshift for the rest of a turn in exchange for that turn completing.

When NOT to use it

  • Your interruptions are 429s or "usage limit reached." A chain does nothing here; fix quota or caching instead (token optimization is the lever).
  • You need every turn on a specific model for reproducibility. A silent downshift to Haiku mid-run can change output quality in ways a later step depends on.
  • You need provider-level resilience. One account cannot fail over to itself; that needs a gateway (covered below).

Stop rule

If all you want is a single automatic backup on overload, add one entry and stop: "fallbackModel": ["sonnet"]. The three-tier chain matters only when you expect Sonnet to be under load at the same time as Opus, which mostly happens during a broad platform incident.

System Requirements

Requirement Detail
Claude Code version v2.1.197+ so the sonnet alias resolves to Sonnet 5; v2.1.154+ for Opus 4.8. Run claude update if unsure.
Model access Every model you list must be reachable on your account. An element you cannot reach is skipped, not fatal, but a chain of unreachable models fails like no chain at all.
Settings location A settings.json you can edit: ~/.claude/settings.json (user) or .claude/settings.json (project).
Provider The examples assume the Anthropic API. On Bedrock, Google Cloud, or Foundry, aliases resolve to different versions and you may need full deployment IDs.

The three aliases and what they resolve to on the Anthropic API today:

Alias Model API ID Input / Output (per MTok) Context Effort default
opus Opus 4.8 claude-opus-4-8 $5 / $25 1M high
sonnet Sonnet 5 claude-sonnet-5 $3 / $15 1M high
haiku Haiku 4.5 claude-haiku-4-5-20251001 $1 / $5 200K (no effort control)

Two details from that table shape a sensible chain. Sonnet 5 carries introductory pricing of $2 / $10 per MTok through August 31, 2026, so the middle tier is cheaper than list right now. And Haiku 4.5 has a 200K context window, not the 1M that Opus and Sonnet carry, so a long session that overflows 200K will not fit on the Haiku tier. Order your chain with that in mind: Haiku is a last resort for capacity reasons, not just quality.

Step-by-Step Setup

Step 1: Confirm your primary model and version

claude --version
claude   # then run /status inside the session
Enter fullscreen mode Exit fullscreen mode

/status shows the active model. If opus is not resolving to Opus 4.8, or sonnet is not Sonnet 5, run claude update first. Expected result: a version at or above 2.1.197 and a recognizable primary model.

Step 2: Test a chain for one session with the flag

Before you persist anything, try the chain with the CLI flag. It accepts a comma-separated list and overrides any saved setting, which makes it the safest way to experiment.

claude --model opus --fallback-model sonnet,haiku
Enter fullscreen mode Exit fullscreen mode

Expected result: the session starts on Opus. You will not see the fallbacks unless an overload actually occurs, at which point Claude Code prints a notice naming the model it switched to.

Step 3: Persist the chain in settings.json

Once the flag behaves, move it into settings so every session inherits it. Use either aliases or full model IDs; full IDs pin a version and survive alias changes.

{
  "model": "opus",
  "fallbackModel": ["claude-sonnet-5", "claude-haiku-4-5"]
}
Enter fullscreen mode Exit fullscreen mode

Expected result: new sessions start on Opus with a two-model fallback chain, no flag needed. The --fallback-model flag still wins for any session you launch with it.

Step 4: Verify the trigger conditions, not the happy path

You cannot manufacture a real 529 on demand, so verify the parts you can reason about instead of waiting for an outage. Confirm each element resolves to a model you can reach, and confirm you understand what will not trigger it. Do not rely on an error to tell you the chain is read: Claude Code does not validate fallbackModel at startup (verified on v2.1.208), so a malformed value is silently ignored rather than throwing. That last point, what will not trigger it, is where most misconfigurations hide, so it gets its own section.

What Triggers a Fallback (and What Doesn't)

This is the table to internalize. A fallback fires on availability failures and stays silent on everything else.

Condition HTTP Triggers fallback? What actually happens
Overloaded 529 overloaded_error Yes Switches to the next model in the chain
Model unavailable varies Yes Skips to the next reachable element
Other non-retryable server error 5xx Yes Switches to the next model
Rate limit 429 No Normal retry with backoff, then surfaced
Authentication 401 No Surfaced as an auth error
Billing 402/403 No Surfaced as a billing error
Request too large 413 No Surfaced as a size error
Transport / network n/a No Normal retry, then surfaced

The 429 row is the one that trips people. A rate limit means you have exhausted a quota, and every model in your chain bills against the same account, so switching from Opus to Haiku does not create headroom. Claude Code knows this and refuses to burn a fallback on it. If your logs show fallbacks that never fire during an incident, check whether the incident is actually a 429.

Here is the same logic as a flow:

flowchart TD
    A[Model request] --> B{Response}
    B -->|529 / unavailable / non-retryable 5xx| C{More models in chain?}
    B -->|429 / auth / billing / size| D[Normal retry, then surface error]
    B -->|success| E[Return result for this turn]
    C -->|yes| F[Switch to next model, show notice]
    C -->|no| D
    F --> A
    E --> G[Next message tries primary first again]
Enter fullscreen mode Exit fullscreen mode

Choosing Your Chain Order

The order of the array is the order Claude Code tries, so the array is a priority list, not a set. Two defaults cover most cases, depending on what you optimize for.

Capability-first (["sonnet", "haiku"] under an opus primary) keeps quality as high as availability allows and only drops to Haiku when both larger models are overloaded at once. Use it for interactive work where a downshift is a genuine last resort.

Cost-first (sonnet primary, ["haiku"] fallback) never reaches for Opus at all. Use it in CI and agent loops where throughput and predictable spend matter more than the ceiling. The hybrid routing argument applies here: most turns do not need Opus, so making it the primary just to have a tall chain wastes money on the common case.

One constraint outranks both preferences, and it is easy to miss: context window. Haiku 4.5 carries a 200K window against the 1M that Opus 4.8 and Sonnet 5 provide. A session that has already grown past 200K cannot land on the Haiku tier at all, so on long-context work Haiku is effectively absent from the chain no matter where you place it. If your sessions routinely run large, keep the chain on the 1M-window tiers and accept that a simultaneous Opus-and-Sonnet outage will fail the turn rather than silently truncate context.

What the Switch Looks Like

A fallback is never silent. When one fires, Claude Code prints a notice in the transcript naming the model it moved to. Because the switch is scoped to the turn, you see that notice again on the next overload rather than a session that quietly settles onto Haiku. Misconfiguration, by contrast, is silent: a malformed fallbackModel value is ignored without a warning (verified on v2.1.208), so a broken chain looks exactly like a working one until an overload finds the gap. To confirm a chain is actually live, do not look for a startup error; audit it from the modelUsage field of a JSON run, as described next.

In non-interactive runs (-p / --print) that emit JSON, the plain-text notice is suppressed, so read the model that actually answered from the modelUsage field of the result message rather than assuming the primary handled the turn. That is the reliable way to audit, after the fact, how often a chain caught something and which tier absorbed the load. If a chain never shows a catch across a real incident window, re-check whether the incident was a 429, which no chain covers.

Common Errors During Setup (and Fixes)

Symptom Cause Fix
Chain never fires during an outage The outage is a 429, not a 529 fallbackModel does not cover rate limits; handle quota separately
Your global chain is silently gone A project .claude/settings.json also defines fallbackModel fallbackModel does not merge across files; the highest-precedence file supplies the entire chain
A listed model is skipped It is retired, unreachable, or excluded by availableModels Replace retired IDs; an allowlisted-out element is dropped when the chain is read
Only three of your four models run Chains are capped at three after de-duplication Trim the list; extra entries past three are ignored
A typo'd chain element never fires, with no error Typos in fallbackModel elements are silently skipped when the chain is read Double-check spelling yourself; use a valid alias (opus/sonnet/haiku) or a claude- prefixed ID. No startup error will catch this
Fallback ignored in a scripted run Running non-interactively where a flagged request just ends the turn This is the Fable 5 classifier path, not fallbackModel; see the disambiguation below

The no-merge behavior deserves emphasis because it is the opposite of how most array settings work. If you tuned a careful three-tier chain in your user settings and a repo ships a .claude/settings.json with its own single-model fallbackModel, the repo wins entirely and your chain is dropped with no warning. Precedence runs managed settings, then command-line flags, then project-local, then project, then user. Put the chain you actually want in the highest-precedence file that any given session will read.

Team / Multi-Developer Configuration

For one developer, fallbackModel in ~/.claude/settings.json is enough. Across a team, the interesting question is who owns the chain and whether individuals can override it.

Goal Where to put fallbackModel Notes
Personal default ~/.claude/settings.json (user) Lowest precedence; any project file overrides it
Per-repo default .claude/settings.json (project, committed) Overrides user settings for anyone working in the repo
Local tweak .claude/settings.local.json Overrides project for one machine, usually gitignored
Enforced fleet-wide managed settings Highest precedence; individuals cannot override

Two team-specific interactions matter. First, if you also use availableModels to restrict which models developers may run, any fallback element outside that allowlist is dropped when the chain is read, so an enforced chain and an allowlist have to agree. Second, because fallback chains do not merge, a committed project chain fully replaces each developer's personal one inside that repo. That is usually what you want for CI and shared agents, but it means a developer who tuned a personal chain loses it silently while working in the repo. Document the project chain so nobody debugs a "missing" fallback that was overridden by design.

A reasonable committed project chain for a team that runs agents in CI:

{
  "model": "sonnet",
  "fallbackModel": ["haiku"],
  "availableModels": ["sonnet", "haiku"]
}
Enter fullscreen mode Exit fullscreen mode

That keeps CI on the cheaper Sonnet tier, falls back to Haiku on overload, and forbids anyone from quietly switching a CI job to Opus.

Advanced: Cross-Provider Failover via a Gateway

A fallback chain has a hard ceiling: every model in it lives on the same Anthropic account. When Anthropic itself has a broad incident, all three tiers are overloaded at once, and there is nothing left in the chain to try. The March 18, 2026 outage that ran past three hours is the shape of failure a same-account chain cannot cover.

Provider-level resilience needs a layer above Claude Code. Point Claude Code at a gateway with ANTHROPIC_BASE_URL, and the gateway (rather than your one account) decides where a request lands. ANTHROPIC_BASE_URL changes where requests go, not which model answers, so a fallbackModel chain still works underneath it for model-level failover, while the gateway adds provider-level failover on top.

An aggregation gateway such as ofox exposes one OpenAI- and Anthropic-compatible endpoint that fronts many providers, so a chain can cross from a Claude model to a non-Claude one when Anthropic as a whole is unavailable, which a native fallbackModel chain physically cannot do. The trade-off is that you are now trusting a second hop, and you configure routing at the gateway instead of in settings.json. For the Claude Code side of that setup, see the Claude Code + ofox configuration guide; for the cost-driven version of the same routing idea, see hybrid model routing.

One disambiguation before the alternatives. Claude Code also has a feature literally called "automatic model fallback," and it is not this one. That mechanism is specific to Fable 5: when a safety classifier flags a request (most often cybersecurity or biology work), Claude Code reruns it on Opus and shows a notice. It has nothing to do with overloads or the fallbackModel chain. If you see fallbacks on a Fable 5 session that you did not configure, that is the classifier. Running claude --safe-mode disables your local customizations (CLAUDE.md, skills, hooks, MCP), so it isolates whether those are tripping it, but safe mode still sends things like your git status and directory names, so repository content itself can trip the classifier even then.

Alternatives That Handle Failover

fallbackModel is the built-in, zero-dependency option and should be your first choice for model-level overload resilience. When you need more, these are the layers above it.

  • ofox exposes a single Anthropic-compatible endpoint fronting multiple providers, so failover can cross from Claude to another model's family during a full Anthropic incident. Best when provider-level resilience matters more than staying on one vendor.
  • LiteLLM is an open-source proxy with its own retry and fallback list across providers. Best when you want to self-host the routing layer and already run infrastructure.
  • OpenRouter is an aggregator with automatic provider fallback for a given model. Best for breadth of model catalog with minimal setup.
  • Portkey is a gateway with configurable fallback and load-balancing policies. Best when you want routing rules rather than a static list, plus observability.

All four sit above Claude Code and complement, rather than replace, a fallbackModel chain: keep the chain for cheap in-CLI model failover, and add a gateway for the provider-level case.

FAQ

What is fallbackModel in Claude Code?

It is a settings.json key, and a --fallback-model CLI flag, that lists backup models Claude Code tries in order when the primary is overloaded or unavailable. You can list up to three. A switch lasts for the current turn only; the next message tries your primary again first.

Does Claude Code fall back automatically when it hits a 529 error?

Only if you configured fallbackModel. A 529 is overloaded_error, one of the conditions that triggers a switch. With nothing configured, Claude Code retries the same model with backoff and then surfaces the error.

Does fallbackModel help with rate limit (429) errors?

No. Authentication, billing, rate-limit (429), request-size, and transport errors never trigger a switch. A 429 means you hit your own quota, and every model in the chain bills against the same account, so switching tiers adds no headroom.

How many fallback models can Claude Code use?

Three. Chains are capped at three after duplicate removal, and extra entries are ignored. A common chain is opus, then sonnet, then haiku.

How do I set a fallback model in Claude Code?

For one session, launch with claude --fallback-model sonnet,haiku. To persist it, add a fallbackModel array to settings.json, for example ["claude-sonnet-5", "claude-haiku-4-5"]. The flag beats the setting.

Does the fallback model stay active for the whole session?

No. A switch applies to the current turn only, so a transient overload does not lock the session onto a lower tier.

What is the difference between fallbackModel and automatic model fallback?

fallbackModel (fallback model chains) covers availability, firing on overload or unavailability. Automatic model fallback is a separate Fable 5 mechanism where a safety classifier reroutes a flagged request to Opus. They only share the word fallback.

Can Claude Code fall back to a non-Anthropic model?

Not through fallbackModel. Every element resolves to a Claude model on the same account, so a full Anthropic outage takes the whole chain down together. Cross-provider failover needs a gateway that fronts more than one provider.


Originally published on ofox.ai/blog.

Top comments (0)