Skip to main content

Overview

Failover is part of virtual models. Every redirect with two or more targets fails over between them: when the target a request was sent to returns a failover-eligible error, GoModel retries the request against the redirect’s remaining available targets, in declared order, and stops at the first success. The redirect’s load-balancing strategy decides only which target is tried first: Pick Failover when the target list is a priority order — always use the best model unless it is down, and only then cascade to the backups. For the other strategies the editor shows a Failover checkbox, on by default. Untick it (or set failover: false as code) when a redirect should only balance and a failed request should return its error, for example when the targets are not interchangeable and a client handles retries itself. The Failover strategy always fails over, so the checkbox is not offered there.

Configure a failover chain

In the dashboard, open Models and edit the model you want to protect: the model is already pinned as the first target, so add the fallbacks below it in priority order and save — the strategy defaults to Failover. To fail over under a new name instead, create a virtual model, list the targets in priority order, and pick Failover in the Load-balancing strategy dropdown. Weights and session keeping do not apply to this strategy, so the editor hides them. Removing the pinned row turns the entry into a plain redirect: requests for the model go to the remaining targets instead. As code (config.yaml or the VIRTUAL_MODELS environment variable):
A target may also name another virtual model (chaining); the sweep then tries every concrete model behind it.

When it runs

Failover is attempted only after an attempt returns:
  • 5xx
  • 429, including a rate limit GoModel itself enforces on the target — a saturated target is skipped while another target has capacity
  • model unavailable, unsupported, or not found style errors
  • upstream failure messages relayed with a 4xx status (aggregator providers such as OpenCode Zen can report a transient failure of their own upstream as 400 "Upstream request failed")
It applies to translated /v1/chat/completions, /v1/responses, and /v1/messages requests. The request log shows every attempt, so a served failover is visible in the audit trail and priced at the model that answered. A request that names its provider in the provider field bypasses virtual models and reaches the concrete model directly. It still gets the chain of a virtual model that shadows exactly that model and lists it as a target (the shape the Models page creates for a real model), since that virtual model adds failover to the model rather than replacing it. Set FAILOVER_ENABLED=false (or failover.enabled: false) to switch the sweep off globally; a workflow can also turn it off for its scope. The chosen target is still served, without retries.

Migrating from failover rules

Earlier releases managed failover as separate per-model mappings (the shuffle icon on the Models page and the failover.rules configuration). Both are converted automatically:
  • Dashboard-managed mappings become virtual models with the failover strategy that shadow their primary model. The conversion runs once at startup and then removes the old failover_rules store (any of its historical shapes). When the primary model already has a plain per-model setting (a slowdown or description set from the Models page), the mapping is merged into it and the setting is kept. A primary that already has a redirect, a path-scoped setting, or is disabled is logged and skipped, and the store is kept until it is resolved — add its fallbacks as targets of that virtual model with the failover strategy, then delete the row. A primary listed in disabled_models converts as a disabled virtual model: its fallbacks are kept but inactive until you enable it from the Models page.
  • failover.rules, manual_rules_path, FAILOVER_RULES_JSON, and disabled_models still load and are translated into configuration-managed virtual models on every start, with a deprecation warning. A rule whose primary model has a virtual model in the dashboard is skipped with a warning, so it never replaces that virtual model’s routing. Move the rules under virtual_models at your convenience.
Last modified on August 29, 2026