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"]
}
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
/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
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"]
}
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]
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"]
}
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.
Sources Checked for This Refresh
- Claude Code model configuration docs, Fallback model chains section (verified 2026-07-15): https://code.claude.com/docs/en/model-config
- Claude Code settings reference,
fallbackModelkey (verified 2026-07-15): https://code.claude.com/docs/en/settings - Anthropic API errors reference, 529
overloaded_error(verified 2026-07-15): https://platform.claude.com/docs/en/api/errors - Anthropic models overview, pricing and context windows for Opus 4.8 / Sonnet 5 / Haiku 4.5 (verified 2026-07-15): https://platform.claude.com/docs/en/about-claude/models/overview
- Hands-on verification on Claude Code v2.1.208 (2026-07-15): malformed and typo’d
fallbackModelvalues are accepted with no startup error and silently skipped; the answering model was confirmed from themodelUsagefield of--printJSON output.


