Troubleshooting the LLM Gateway
The gateway answers errors in the shape of the API that was called, so Anthropic and OpenAI SDKs report them normally. Every refusal also carries an x-willow-deny-reason header, which is the quickest way to tell refusals apart.
Status codes differ by API on purpose. Claude Code silently retries 403, 429, and 5xx responses, which would hang the session, so every refusal on the Anthropic API is a 400. The OpenAI APIs use the conventional status for each reason.
Errors
| Message | x-willow-deny-reason | Anthropic API | OpenAI APIs |
|---|---|---|---|
Invalid or expired Willow token | none | 401 | 401 |
The Willow LLM gateway is not enabled for this organization | not_enabled | 400 | 403 |
Model … is not available in your organization's LLM gateway | model_not_found | 400 | 404 |
You don't have access to model … | not_entitled | 400 | 403 |
Model … is served by …; call it through … | unsupported_api | 400 | 400 |
The "…" budget of $… for this month is used up | budget_exceeded | 400 | 403 |
Willow blocked this prompt (…), or the guard's own message | guard_blocked | 400 | 400 |
Willow is temporarily unavailable | none | 503 | 503 |
The model provider is unreachable | none | 502 | 502 |
Errors from the provider itself, such as a rejected key or a provider rate limit, are passed through with the provider's own status and body.
Invalid or expired Willow token
The client sent no key, a key Willow does not recognize, or a credential that has expired. The user signs in again:
npx -y @mcp-s/mcp@latest auth login --refresh --base-url <your MCP URL>
The auth token command prints the saved credential without checking it, so it keeps printing an expired one until the user signs in again. A credential that Willow revoked can keep working for up to a minute.
Not enabled
The gateway switch on the Overview tab is off, or the LLM Gateway beta is not enabled for the organization. Turn the gateway on, or ask Willow Support to enable the beta. A change takes up to a minute to reach the gateway.
Model not found
No usable model matches the name the client sent. The message names it. Check that:
- A model on the Models tab has that name as its Alias or Provider model id. Clients such as Claude Code send their own model ids. See How a request finds its model.
- The model and its provider are both enabled.
- The provider has a key, and an OpenAI-compatible provider has a Base URL.
- If the client sent no model, a default model is set.
No access to the model
The model exists, but Who can use it lists groups the caller is not in. Add the user to one of those groups, or add one of their groups to the model. Group changes take up to a minute to reach the gateway.
Served through another API
The client called an Anthropic model on an OpenAI API, or the other way around. The gateway does not translate between them. Use the base URL for the model's API: the gateway URL for Anthropic models, the gateway URL followed by /v1 for OpenAI and OpenAI-compatible models. See Which URL each API uses.
Budget used up
A budget set to Block the call is spent for this month, and no usable fallback is configured. The message names the budget. Raise its limit, give it a fallback model, or wait for the 1st of the month (UTC). If the budget has a fallback and calls are still blocked, the fallback is also over a budget, the caller cannot use it, or it is served on a different API.
Blocked by a guard
A runtime guard that applies to prompts blocked the newest message. Find the guard in Monitor > Logs on the call's llm_call entry, or in its alert. To exempt gateway traffic from it, turn off Apply to Prompts on the guard, or narrow it with filters. See Guard LLM Prompts.
Willow is temporarily unavailable
The gateway could not reach Willow to check the token, settings, spend, or guards. Claude Code retries these silently, so users see a hung session. The common causes:
- Isolated hybrid gateway. With Isolated Mode on and at least one active guard that applies to prompts, guards cannot be evaluated, and every call fails. See When guards cannot be evaluated.
- Self-hosted gateway that cannot reach Willow SaaS. On hybrid, check the gateway's
DB_SERVICE_URLandAUTH_SECRET. See LLM gateway on hybrid. - Write-Only KMS. Willow cannot decrypt provider keys that were encrypted with your own KMS key, so the gateway cannot load your settings. The LLM Gateway is not supported with Write-Only KMS.
The model provider is unreachable
The gateway could not open a connection to the provider. Check the provider's Base URL. On a self-hosted gateway, check that your cluster allows outbound HTTPS to the provider.
The Connect tab URL returns 404
On a hybrid deployment, the Connect tab shows the gateway on your run hostname, https://willow.<your-domain>/llm. If that returns 404, the /llm path is reaching run instead of the gateway: the gateway is not deployed in your cluster, or its ingress rule is missing. See LLM gateway on hybrid.
Calls are missing from Usage
- You lack Monitoring & Shadow AI > View, so the tab is hidden for you.
- The client is calling the provider directly. Check that
ANTHROPIC_API_KEYandANTHROPIC_AUTH_TOKENare not set for Claude Code, since they take precedence over the gateway key. See Claude Code. - The calls were refused before the gateway applied budgets and guards: an invalid token, a gateway that is off, an unknown model, missing access, or the wrong API. Those refusals are not recorded. See The audit log.