Hermes Agent Fallback Providers: Staying Up When a Provider Fails
Configure Hermes Agent to automatically switch providers when your primary model fails.

This reference page covers the fallback provider system in Hermes Agent, an AI agent runtime that connects to over 30 model providers. With fallback providers configured, an agent can automatically switch to a backup provider when the primary model fails due to rate limits, server errors, or auth failures, preserving the conversation and continuing without manual intervention.
What It Does
Hermes Agent's fallback system provides three layers of resilience that keep sessions running when providers encounter issues:
- Credential pools rotate across multiple API keys for the same provider (tried first)
- Primary model fallback automatically switches to a different provider:model pair when the main model fails
- Auxiliary task fallback provides independent provider resolution for side tasks like vision, compression, and web extraction
Credential pools handle same-provider rotation (for example, multiple OpenRouter keys). This page covers cross-provider fallback. Both are optional and work independently.
The fallback system is turn-scoped. Each new user message starts with the primary model restored. If the primary fails mid-turn, fallback activates for that turn only. On the next message, Hermes tries the primary again. Within a single turn, fallback activates at most once. If the fallback also fails, normal error handling takes over (retries, then an error message). This prevents cascading failover loops within a turn while giving the primary model a fresh chance every turn.
When fallback triggers, Hermes resolves credentials for the fallback provider, builds a new API client, swaps the model, provider, and client in-place, resets the retry counter, and continues the conversation. The switch is seamless. Conversation history, tool calls, and context are preserved. The agent continues from exactly where it left off, just using a different model.
Fallback resets the prompt cache. Prompt caches are keyed to the model (and on most providers, the account) serving the request. When fallback fires, the new provider:model has no cached prefix for the conversation, so the next request re-reads the entire history at full input-token price instead of the approximately 75-90% discounted cached rate. The same applies when the turn ends and the primary is restored. That first request back on the primary is a full re-read too, unless the primary's cache TTL has not expired. This is unavoidable. It is the cost of staying alive through an outage. A long session that bounces between providers can cost noticeably more than one that stays put.
Setup
Primary Model Fallback Configuration
The easiest path to configure fallback providers is the interactive manager. Run this command in your terminal:
hermes fallback
hermes fallback reuses the provider picker from hermes model. It uses the same provider list, same credential prompts, and same validation. Use the subcommands add, list (alias ls), remove (alias rm), and clear to manage the chain. Changes persist under the top-level fallback_providers: list in config.yaml.
If you prefer to edit the YAML directly, add a top-level fallback_providers list to ~/.hermes/config.yaml. Here is the structure:
fallback_providers:
- provider: openrouter
model: anthropic/claude-sonnet-4
Each entry requires both provider and model. Entries missing either field are ignored.
There are no environment variables for the primary fallback chain. Configure it exclusively through config.yaml or hermes fallback. This is intentional. Fallback configuration is a deliberate choice, not something a stale shell export should override.
Legacy Configuration Note
fallback_providers (plural, list) is the current config shape and supports multiple fallbacks tried in order. fallback_model (singular) is the legacy single-fallback key. Hermes still honors it for backward compatibility, but hermes fallback writes the current fallback_providers key and migrates legacy config on write. When both are set, fallback_providers takes priority.
Custom Endpoint Fallback
For a custom OpenAI-compatible endpoint, add base_url and optionally key_env:
fallback_providers:
- provider: custom
model: my-local-model
base_url: http://localhost:8000/v1
key_env: MY_LOCAL_KEY # env var name containing the API key
Auxiliary Task Fallback Configuration
Each auxiliary task can be configured independently in config.yaml. Here is the full structure:
auxiliary:
vision:
provider: "auto" # auto | openrouter | nous | codex | main | anthropic
model: "" # e.g. "openai/gpt-4o"
base_url: "" # direct endpoint (takes precedence over provider)
api_key: "" # API key for base_url
web_extract:
provider: "auto"
model: ""
compression:
provider: "auto"
model: ""
fallback_chain: # optional, task-specific fallback policy
- provider: openrouter
model: inclusionai/ring-2.6-1t:free
skills_hub:
provider: "auto"
model: ""
mcp:
provider: "auto"
model: ""
Every task above follows the same provider/model/base_url pattern. Each task can also declare its own fallback_chain. If omitted, provider: auto uses the top-level fallback_providers chain before Hermes' built-in auxiliary discovery chain.
Context compression is configured under auxiliary.compression:
auxiliary:
compression:
provider: main # Same provider options as other auxiliary tasks
model: google/gemini-3-flash-preview
base_url: null # Custom OpenAI-compatible endpoint
And the primary fallback chain uses:
fallback_providers:
- provider: openrouter
model: anthropic/claude-sonnet-4
# base_url: http://localhost:8000/v1 # Optional custom endpoint
All three (auxiliary, compression, fallback) work the same way. Set provider to pick who handles the request, model to pick which model, and base_url to point at a custom endpoint (overrides provider).
Delegation Provider Override
Subagents spawned by delegate_task inherit the parent agent's primary fallback chain. You can still route subagents to a different primary provider:model pair for cost optimization:
delegation:
provider: "openrouter" # override provider for all subagents
model: "google/gemini-3-flash-preview" # override model
# base_url: "http://localhost:1234/v1" # or use a direct endpoint
# api_key: "local-key"
Cron Job Providers
Cron jobs inherit your configured fallback_providers chain (or legacy fallback_model) when they create an agent. To use a different primary provider for a cron job, configure provider and model overrides on the cron job itself:
cronjob (
action = "create",
schedule = "every 2h",
prompt = "Check server status",
provider = "openrouter",
model = "google/gemini-3-flash-preview"
)
Configuration Reference
Primary Fallback Providers Table
The following table lists all supported providers for the primary fallback_providers list, their required configuration values, and any optional settings.
| Provider | Config Value | Requirements |
|---|---|---|
| OpenRouter | openrouter | OPENROUTER_API_KEY |
| Nous Portal | nous | hermes setup --portal (fresh) or hermes auth add nous (OAuth) |
| OpenAI Codex | openai-codex | hermes model (ChatGPT OAuth) |
| GitHub Copilot | copilot | COPILOT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN |
| GitHub Copilot ACP | copilot-acp | External process (editor integration) |
| Anthropic | anthropic | ANTHROPIC_API_KEY or Claude Code credentials |
| z.ai / GLM | zai | GLM_API_KEY |
| Kimi / Moonshot | kimi-coding | KIMI_API_KEY |
| MiniMax | minimax | MINIMAX_API_KEY |
| MiniMax (China) | minimax-cn | MINIMAX_CN_API_KEY |
| DeepSeek | deepseek | DEEPSEEK_API_KEY |
| NVIDIA NIM | nvidia | NVIDIA_API_KEY (optional: NVIDIA_BASE_URL) |
| GMI Cloud | gmi | GMI_API_KEY (optional: GMI_BASE_URL) |
| Upstage Solar | upstage (alias solar) | UPSTAGE_API_KEY (optional: UPSTAGE_BASE_URL) |
| StepFun | stepfun | STEPFUN_API_KEY (optional: STEPFUN_BASE_URL) |
| Ollama Cloud | ollama-cloud | OLLAMA_API_KEY |
| Google AI Studio | gemini | GOOGLE_API_KEY (alias: GEMINI_API_KEY) |
| xAI (Grok) | xai (alias grok) | XAI_API_KEY (optional: XAI_BASE_URL) |
| xAI Grok OAuth (SuperGrok) | xai-oauth (alias grok-oauth) | hermes model -> xAI Grok OAuth (browser login; SuperGrok subscription) |
| AWS Bedrock | bedrock | Standard boto3 auth (AWS_REGION + AWS_PROFILE or AWS_ACCESS_KEY_ID) |
| Qwen Portal (OAuth) | qwen-oauth | hermes model (Qwen Portal OAuth; optional: HERMES_QWEN_BASE_URL) |
| MiniMax (OAuth) | minimax-oauth | hermes model (MiniMax portal OAuth) |
| OpenCode Zen | opencode-zen | OPENCODE_ZEN_API_KEY |
| OpenCode Go | opencode-go | OPENCODE_GO_API_KEY |
| Kilo Code | kilocode | KILOCODE_API_KEY |
| Xiaomi MiMo | xiaomi | XIAOMI_API_KEY |
| Arcee AI | arcee | ARCEEAI_API_KEY |
| Alibaba / DashScope | alibaba | DASHSCOPE_API_KEY |
| Alibaba Coding Plan | alibaba-coding-plan | ALIBABA_CODING_PLAN_API_KEY (falls back to DASHSCOPE_API_KEY) |
| Kimi / Moonshot (China) | kimi-coding-cn | KIMI_CN_API_KEY |
| Tencent TokenHub | tencent-tokenhub | TOKENHUB_API_KEY |
| Microsoft Foundry | azure-foundry | AZURE_FOUNDRY_API_KEY + AZURE_FOUNDRY_BASE_URL |
| LM Studio (local) | lmstudio | LM_API_KEY (or none for local) + LM_BASE_URL |
| Hugging Face | huggingface | HF_TOKEN |
| Custom endpoint | custom | base_url + key_env (see below) |
Auxiliary Task Provider Options
These options apply to auxiliary:, compression:, and fallback_providers: entries only. "main" is not a valid value for your top-level model.provider. For custom endpoints, use provider: custom in your model: section.
| Provider | Description | Requirements |
|---|---|---|
"auto" | Try providers in order until one works (default) | At least one provider configured |
"openrouter" | Force OpenRouter | OPENROUTER_API_KEY |
"nous" | Force Nous Portal | hermes auth |
"codex" | Force Codex OAuth | hermes model -> Codex |
"main" | Use whatever provider the main agent uses (auxiliary tasks only) | Active main provider configured |
"anthropic" | Force Anthropic native | ANTHROPIC_API_KEY or Claude Code credentials |
Fallback Chain Entry Options
Each entry in a fallback_chain list (whether top-level or per-task) can include these fields:
provider(required): The provider identifier from the supported providers table.model(optional): The model string. If omitted, the provider's default model is used.base_url(optional): A custom OpenAI-compatible endpoint URL. Takes precedence over provider resolution.api_key(optional): The API key for the custom endpoint. If not set, falls back toOPENAI_API_KEY.timeout(optional, seconds): A per-entry timeout override. Without it, the fallback candidate inherits the task-level timeout. This lets a slower-but-reliable fallback get the budget it actually needs instead of dying on the primary's clock.
How It Works

Primary Model Fallback Trigger Conditions
The fallback activates automatically when the primary model fails with:
- Rate limits (HTTP 429) after exhausting retry attempts
- Server errors (HTTP 500, 502, 503) after exhausting retry attempts
- Auth failures (HTTP 401, 403) immediately (no point retrying)
- Not found (HTTP 404) immediately
- Invalid responses when the API returns malformed or empty responses repeatedly
When triggered, Hermes:
- Resolves credentials for the fallback provider
- Builds a new API client
- Swaps the model, provider, and client in-place
- Resets the retry counter and continues the conversation
Auxiliary Task Auto-Detection Chain
When a task's provider is set to "auto" (the default), Hermes first tries the main provider plus main model for that auxiliary task. If that route is unavailable or later fails with a capacity-style error, Hermes honors user-configured fallback policy before using the built-in discovery chain. The resolution order is:
Main provider + main model -> auxiliary.<task>.fallback_chain ->
fallback_providers / fallback_model -> built-in auxiliary discovery chain
The task-specific chain is most precise and wins when present. The top-level fallback_providers chain is the same policy the main agent uses, so free-only or same-provider fallback rules apply to auxiliary tasks on auto as well.
Built-in text discovery chain (compression, web extract, title generation, and others):
OpenRouter -> Nous Portal -> Custom endpoint -> Codex OAuth ->
API-key providers (z.ai, Kimi, MiniMax, Xiaomi MiMo, Hugging Face, Anthropic) -> give up
Built-in vision discovery chain:
Main provider (if vision-capable) -> OpenRouter -> Nous Portal ->
Codex OAuth -> Anthropic -> Custom endpoint -> give up
Those built-in chains are a convenience fallback for users who have not declared a task-specific or main fallback policy.
Auxiliary Capacity-Error Fallback
When you set an explicit auxiliary provider (for example, auxiliary.vision.provider: glm), Hermes treats that as your preferred choice. But if the provider literally cannot serve the request because of a capacity error (HTTP 402 payment required, HTTP 429 daily-quota exhaustion, connection failure), Hermes falls back through a layered chain instead of failing silently:
- Primary aux provider (the one you configured, tried first, always)
auxiliary.<task>.fallback_chain(your per-task override list, if you wrote one)- Main agent provider + model (last-resort safety net, always tried, even if you did not write a chain)
- Warn + re-raise (if every layer fails, Hermes logs
Auxiliary <task>: all fallbacks exhaustedat WARNING level and re-raises the original error)
Transient HTTP 429 rate limits with Retry-After headers are treated as request constraints, not capacity problems. They respect your explicit provider choice and do not trigger the fallback ladder. Only daily or monthly quota exhaustion, payment errors, and connection failures bypass the explicit-provider gate.
For users on provider: auto (no explicit aux provider), the existing auto-detection chain runs in place of steps 2-3. Its first step is already the main agent model, so auto users get the same outcome with zero config.
Provider Quota Errors That Trigger Fallback
Hermes recognizes these error strings as capacity-equivalent to 402 credit exhaustion (not transient rate limits):
- Bedrock / LiteLLM:
Too many tokens per day,daily limit,tokens per day - Vertex AI / GCP:
quota exceeded,resource exhausted,RESOURCE_EXHAUSTED - Generic:
daily quota,quota_exceeded
If your provider returns a different phrase for daily-quota exhaustion and Hermes does not trigger fallback, that is a bug. Open an issue with the exact error string.
Direct Endpoint Override
For any auxiliary task, setting base_url bypasses provider resolution entirely and sends requests directly to that endpoint:
auxiliary:
vision:
base_url: "http://localhost:1234/v1"
api_key: "local-key"
model: "qwen2.5-vl"
base_url takes precedence over provider. Hermes uses the configured api_key for authentication, falling back to OPENAI_API_KEY if not set. It does not reuse OPENROUTER_API_KEY for custom endpoints.
Context Compression Fallback
Context compression uses the auxiliary.compression config block to control which model and provider handles summarization:
auxiliary:
compression:
provider: "auto" # auto | openrouter | nous | main
model: "google/gemini-3-flash-preview"
Older configs with compression.summary_model / compression.summary_provider / compression.summary_base_url are automatically migrated to auxiliary.compression.* on first load (config version 17).
If no provider is available for compression, Hermes drops middle conversation turns without generating a summary rather than failing the session.
Requirements and Limitations
Prerequisites
- Hermes Agent must be installed and configured with at least one primary provider.
- For each fallback provider you want to use, the corresponding environment variable or authentication method must be set up. See the Supported Providers table for exact requirements.
- The
fallback_providerslist must be configured in~/.hermes/config.yamlor via thehermes fallbackinteractive manager.
Where Fallback Works
| Context | Fallback Supported |
|---|---|
| CLI sessions | Yes |
| Messaging gateway (Telegram, Discord, etc.) | Yes |
| Subagent delegation | Yes (subagents inherit the parent fallback chain) |
| Cron jobs | Yes (cron agents inherit configured fallback providers) |
Auxiliary tasks on provider: auto | Yes (try per-task fallback, then the main fallback chain before built-in aux discovery) |
Limitations
- Fallback is turn-scoped. Each new user message starts with the primary model restored. If the primary fails mid-turn, fallback activates for that turn only. On the next message, Hermes tries the primary again.
- Within a single turn, fallback activates at most once. If the fallback also fails, normal error handling takes over (retries, then error message). This prevents cascading failover loops within a turn.
- Fallback resets the prompt cache. When fallback fires, the new provider:model has no cached prefix for the conversation, so the next request re-reads the entire history at full input-token price. A long session that bounces between providers can cost noticeably more than one that stays put.
- There are no environment variables for the primary fallback chain. Configure it exclusively through
config.yamlorhermes fallback. "main"is not a valid value for your top-levelmodel.provider. It is only valid for auxiliary task configuration.- For delegation and cron jobs, there is no automatic fallback. Only provider override is supported.
- If your provider returns a different phrase for daily-quota exhaustion and Hermes does not trigger fallback, that is a bug. Open an issue with the exact error string.
Troubleshooting
Fallback Does Not Trigger
If fallback does not activate when you expect it to, check the following:
- Ensure the
fallback_providerslist is correctly formatted inconfig.yaml. Each entry requires bothproviderandmodel. Entries missing either field are ignored. - Verify that the fallback provider's credentials are set correctly. For example, if using OpenRouter as a fallback, ensure
OPENROUTER_API_KEYis set. - For auxiliary tasks with an explicit provider, transient HTTP 429 rate limits with
Retry-Afterheaders are treated as request constraints, not capacity problems. They do not trigger the fallback ladder. Only daily or monthly quota exhaustion, payment errors, and connection failures bypass the explicit-provider gate. - If you are using a custom endpoint, ensure
base_urlandkey_env(orapi_key) are correctly configured.
Fallback Triggers But Fails
If the fallback provider is selected but the request still fails:
- Check that the fallback provider's credentials are valid and have not expired.
- Verify that the model specified in the fallback entry exists and is accessible with the provided credentials.
- If using a custom endpoint, ensure the endpoint is running and reachable.
- Within a single turn, fallback activates at most once. If the fallback also fails, normal error handling takes over (retries, then error message). The next user message will try the primary model again.
Legacy Configuration Not Working
If you have an older config with fallback_model (singular) and it is not being used:
fallback_providers(plural, list) takes priority when both are set.- Run
hermes fallbackto migrate legacy config to the current format. The command writes the currentfallback_providerskey and migrates legacy config on write.
Context Compression Not Working
If context compression is failing and no summary is generated:
- Check the
auxiliary.compressionconfiguration block. Ensureproviderandmodelare set correctly. - If no provider is available for compression, Hermes drops middle conversation turns without generating a summary rather than failing the session. This is expected behavior.
- Older configs with
compression.summary_model/compression.summary_provider/compression.summary_base_urlare automatically migrated toauxiliary.compression.*on first load (config version 17). If migration does not happen, manually update your config.
Quota Error Not Triggering Fallback
If your provider returns a daily-quota exhaustion error but Hermes does not trigger fallback:
- Check the exact error string. Hermes recognizes these as capacity-equivalent to 402 credit exhaustion:
Too many tokens per day,daily limit,tokens per day,quota exceeded,resource exhausted,RESOURCE_EXHAUSTED,daily quota,quota_exceeded. - If your provider returns a different phrase, that is a bug. Open an issue with the exact error string.
Auxiliary Task All Fallbacks Exhausted
If you see a log message like Auxiliary <task>: all fallbacks exhausted at WARNING level:
- This means every layer of the fallback chain (primary aux provider, per-task fallback chain, main agent provider + model) has failed.
- The original error is re-raised. Check the error details to determine which provider failed and why.
- Verify that at least one provider in the chain has valid credentials and is accessible.
Examples
OpenRouter as Fallback for Anthropic Native
model:
provider: anthropic
default: claude-sonnet-4-6
fallback_providers:
- provider: openrouter
model: anthropic/claude-sonnet-4
Nous Portal as Fallback for OpenRouter
model:
provider: openrouter
default: anthropic/claude-opus-4
fallback_providers:
- provider: nous
model: nous-hermes-3
Local Model as Fallback for Cloud
fallback_providers:
- provider: custom
model: llama-3.1-70b
base_url: http://localhost:8000/v1
key_env: LOCAL_API_KEY
Codex OAuth as Fallback
fallback_providers:
- provider: openai-codex
model: gpt-5.3-codex
Per-Task Fallback Chain for Vision
auxiliary:
vision:
provider: glm
model: glm-4v-flash
fallback_chain:
- provider: openrouter
model: google/gemini-3-flash-preview
- provider: nous
model: anthropic/claude-sonnet-4
compression:
provider: openrouter
fallback_chain:
- provider: openai
model: gpt-4o-mini
timeout: 240 # optional - this candidate's own deadline (seconds)
Sources & References
This page was researched from 1 independent source, combined and verified for completeness.
- 1.Fallback ProvidersOfficial documentation · primary source
The #1 AI Newsletter
The most important ai updates, guides, and fixes — one weekly email.
No spam, unsubscribe anytime. Privacy policy