OpenClaw "Model login expired" — and your fallbacks aren't used
Your Codex agent stops working and the gateway logs
Model login expired on the gateway for openai. Re-auth with `openclaw models auth
login --provider openai` — and the worst part is that the cross-provider fallbacks
you set up never kick in. Every turn just errors.
The immediate fix is to re-authenticate the provider
(openclaw models auth login --provider openai). But the reason your
failover didn't catch it is separate: on a unified-provider OpenClaw
(2026.5.30 and later) a Codex primary used to have every non-Codex
fallback stripped out of the live config — so there was nothing to fail over to
(next=none), no matter how many fallbacks your instance listed.
Model login expired on the gateway for openai.
Re-auth with `openclaw models auth login --provider openai`
# and in the model-fallback decision log:
[model-fallback/decision] requested=openai/gpt-5.5 candidate=openai/gpt-5.5 \
reason=auth_permanent next=none # <- next=none: no fallback to fail over to What "Model login expired" means (and the immediate fix)
The banner means the OAuth credential for that provider — here openai /
openai-codex — can no longer mint a valid access token, so the gateway can't
authenticate the model. The Codex OAuth has expired, been revoked, or its refresh token is
spent. The fix the message tells you to run is the right first move:
openclaw models auth login --provider openai
That re-runs the OAuth flow and writes fresh tokens. If the login itself fails, or the
runtime keeps preferring a stale saved profile, add --force to delete the
saved auth profile for that provider in the agent directory and re-run the flow clean.
Upstream reports show the openai-codex OAuth refresh failing on its own every ~10–30 days
(openclaw/openclaw#57399),
sometimes refreshing even when the access token is still valid
(#62247) and
not persisting the new token to disk
(#52037) —
so periodic re-auth on a self-hosted Codex setup is, unfortunately, expected.
Why your configured fallbacks didn't catch it (next=none)
Re-auth stops the bleeding, but it doesn't answer the real question: you configured
anthropic/openrouter fallbacks precisely so a Codex outage wouldn't take you down — why did
every turn just error instead of failing over? The decision log gives it away:
next=none. There was nothing in the fallback chain to try, even though the
instance's stored fallback_models listed several cross-provider models.
The cause is in how the gateway config is generated for a Codex primary.
On a unified-provider OpenClaw (2026.5.30 and later), a Codex primary like
openai-codex/gpt-5.5 is rewritten to the unified openai/gpt-5.5
form. The earlier code filtered the fallback list while doing that rewrite and kept
only the openai-codex/* entries — silently dropping every
anthropic/*, openrouter/*, and ollama/* fallback. So
an agent whose primary was Codex and whose fallbacks were all other providers
ended up with a live config of {"primary":"openai/gpt-5.5"} and
no fallbacks at all. When the Codex login expired, the failover you
configured wasn't there to catch it.
This was a regression from the 2026.5.30 unified-OpenAI-provider migration: before it, a mixed Codex-plus-other agent kept its fallbacks through a per-agent runtime; the unified path routed the rewrite through the codex harness, which stripped them. Current OpenClaw preserves non-Codex fallbacks on the unified-provider shape (a fallback to anthropic just uses anthropic's own runtime), while still dropping them on the legacy per-agent-runtime shape, where a Codex agent genuinely can't drive another provider. If you're on an affected build, upgrade and then regenerate the config with one restart so the preserved fallbacks land in the live config.
The ollama fallback that drops for a different reason
One gotcha that survives even after cross-provider fallbacks are preserved:
ollama/* fallbacks can still vanish, and not because of the Codex rewrite.
Fallback models are validated against the model catalog and your provider configs
first — before the Codex harness runs. If
models.providers.ollama.models is empty (a common default), every
ollama/* fallback fails that validation and is dropped regardless of the
cross-provider fix. anthropic/* and openrouter/* validate fine.
So don't assume "fallbacks preserved" means your ollama entry will fire — populate its
model list so the reference resolves, or use a provider whose catalog is non-empty.
Two things called "fallback" that people mix up
Half the confusion here is vocabulary. OpenClaw has two independent
failover mechanisms, and "Model login expired" with next=none is specifically
a problem with the second one:
- Auth-profile rotation (
auth.order.openai = [account-a, account-b]) swaps credentials within the same provider when one account is exhausted or unauthenticated. It does not change the model. - The model fallback chain (
agents.defaults.model.fallbacks) fails over to a different model, usually a different provider, when the primary errors. This is the one stripped by the Codex-primary bug. - Per-cron-job fallbacks apply only to scheduled runs, not to live chat — so a cron job can have working failover while interactive chat does not, or vice versa. Check the chain on the surface that's actually failing.
Fix it (self-hosted)
- Re-authenticate the expired provider to clear the immediate stop:
openclaw models auth login --provider openai(add--forceif a stale profile keeps being reused). - Check the live config, not the dashboard. Read the generated gateway
config and look at
agents.defaults.model. If there's only aprimaryand nofallbacks— orfallbackswith onlyopenaivariants when you configured anthropic/openrouter — the chain was stripped. The[model-fallback/decision] ... next=noneline confirms it at runtime. - Upgrade to a build that preserves cross-provider fallbacks, then
regenerate the config with one gateway restart so the non-Codex fallbacks are written
back into the live config:
openclaw gateway stop && openclaw gateway start - Re-check the decision log. After a real Codex error you should now see a
cross-provider candidate in
next=(e.g.next=anthropic/claude-sonnet-4-6) instead ofnext=none— the failover is back.
Note this is config-generation behavior, not something you fix by editing tokens: even a perfectly valid fallback list in your instance settings does nothing if the generated config drops it. The point of failure is the rewrite, not the credentials.
Stop babysitting your OpenClaw box
Fix it once — or stop fixing it for good.
Apply the checklist above and keep self-hosting, or skip the maintenance entirely: run your OpenClaw on managed hosting from $6.90/mo, starting with a 7-day free trial. We handle the stale locks, gateway restarts, version upgrades, and uptime — and you can import your existing instance in a couple of minutes. Cancel anytime.
- Managed hosting handles stale
.jsonl.lockfiles, gateway restarts, and version upgrades for you - Import your existing OpenClaw setup in minutes — keep your channels and configuration
- The optional $199 setup is scoped: no custom development, enterprise/SRE support, or unsupported self-hosting repair
If you would rather compare options first, review OpenClaw cloud hosting or see the best OpenClaw hosting options before deciding.
Related, but not this
- "Your refresh token has already been used" (401) — the OAuth root cause behind a stuck Codex login, where one instance 401s while siblings on the same version work: see OpenClaw Codex OAuth: refresh token already used (401).
- Codex "stopped before confirming the turn was complete" — a quota (429) or completion-idle timeout, a different Codex failure that also ends in a fallback: see why Codex stops before confirming the turn is complete.
- "No API key found for provider openai" after an upgrade — the empty-store case (no profile imported at all), not an expired login: see OpenClaw "No API key found for provider openai" after an upgrade.
How managed hosting avoids this
A stripped fallback chain is a side effect of owning the config-generation and upgrade lifecycle yourself: an old build silently drops the failover you configured, and you only find out when the primary goes down. On managed OpenClaw hosting from Lobsterland, your instance config is regenerated on the current build — cross-provider fallbacks are preserved for a Codex primary, and a config change applies with a managed restart rather than a hand-edit you have to remember. You set a primary and a fallback chain; keeping that chain intact through every upgrade is the platform's job, not yours.
Import your current OpenClaw instance in 1 clickFrequently asked questions
What does "Model login expired on the gateway" mean in OpenClaw?
It means the OAuth credential for that provider (here openai /
openai-codex) can no longer mint a valid access token, so the gateway can't
authenticate the model. The immediate fix is to re-authenticate:
openclaw models auth login --provider openai. If the login itself fails or
keeps reusing a stale profile, add --force to delete the saved profile for
that provider in the agent directory and run the OAuth flow fresh.
Why aren't my configured fallback models used when the Codex login expires?
Because the cross-provider fallbacks you configured may not be in the live gateway config
at all. The decision log shows next=none — there's nothing to fail over to. On
a unified-provider OpenClaw (2026.5.30 and later) a Codex primary used to be
rewritten from openai-codex/* to openai/* while its fallback list
was filtered to keep only openai-codex/* entries — silently
dropping every anthropic, openrouter, or ollama fallback. So when the Codex OAuth expired
there was no cross-provider failover left. Current OpenClaw preserves those non-codex
fallbacks on the unified-provider shape; regenerate the config and restart so the fix
takes effect.
Why does my ollama fallback still not work after the fallbacks are preserved?
ollama fallbacks drop for a different reason, earlier in the pipeline. Fallback models are
validated against the model catalog and your provider configs before the Codex
rewrite runs; if models.providers.ollama.models is empty,
ollama/* fallbacks fail that validation and are dropped regardless of the
cross-provider fix. Anthropic and OpenRouter fallbacks validate fine. If you want ollama as
a real fallback, make sure its model list is populated so the model resolves.
Is auth-profile rotation the same as a model fallback chain?
No — and conflating them is why people misread this. Auth-profile rotation
(auth.order.openai = [account-a, account-b]) swaps credentials within the
same provider when one account is exhausted. A model fallback chain
(agents.defaults.model.fallbacks) fails over to a different model,
usually a different provider, when the primary errors. "Model login expired" with
next=none is a model-fallback-chain problem: the chain is empty. Per-cron-job
fallbacks also apply only to cron runs, not live chat.
How do I confirm the fallback chain is actually in my OpenClaw config?
Read the generated gateway config (not just the dashboard) and look at
agents.defaults.model. If you see only a primary and no fallbacks
key — or fallbacks containing only openai variants when you
configured anthropic/openrouter — the chain was stripped. The decision log line
[model-fallback/decision] ... next=none confirms there's nothing to fail over
to at runtime. After upgrading to a build that preserves cross-provider fallbacks,
regenerate the config (one restart) and re-check that the non-codex fallbacks are present.