BerriAI/litellm · error · HTTPException
byok_auth_unavailable
byok_auth_unavailable
Error message
BYOK credential check requires a database connection.
What it means
BYOK servers keep credentials in the database, so the pre-dispatch ownership check needs prisma_client. When the proxy runs without a database, LiteLLM fails closed: HTTP 503 with error code byok_auth_unavailable instead of skipping the check. The source comment records why — the old early-return silently let any proxy-authenticated caller use BYOK tools during DB outage windows.
Source
Thrown at litellm/proxy/_experimental/mcp_server/server.py:2596
"message": (
"No stored credential found for this BYOK server. "
"Complete the OAuth authorization flow to provide your API key."
),
},
headers={
"WWW-Authenticate": 'Bearer resource_metadata="/.well-known/oauth-protected-resource"'
},
)
return
from litellm.proxy._experimental.mcp_server.db import get_user_credential
from litellm.proxy.proxy_server import prisma_client
if prisma_client is None:
# Fail closed on DB unavailability: returning here previously
# bypassed the ownership check and let any proxy-authenticated
# caller invoke BYOK tools during outage windows.
raise HTTPException(
status_code=503,
detail={
"error": "byok_auth_unavailable",
"server_id": mcp_server.server_id,
"server_name": mcp_server.server_name or mcp_server.name,
"message": "BYOK credential check requires a database connection.",
},
)
credential: Final = await get_user_credential(
prisma_client=prisma_client,
user_id=user_id,
server_id=mcp_server.server_id,
)
_write_byok_cred_cache(user_id, mcp_server.server_id, credential)
if credential is None:
raise HTTPException(
status_code=401,View on GitHub (pinned to 77b7c6c40c)
Solutions
- Set DATABASE_URL, run prisma migrations, and restart the proxy so prisma_client initializes.
- If this deployment genuinely has no DB, remove BYOK servers from its config and use static server credentials.
- Treat the 503 as a health signal: check DB connectivity first; the call succeeds once the DB is reachable.
Defensive patterns
Strategy: retry
Validate before calling
async def db_ready(client: httpx.AsyncClient) -> bool:
r = await client.get(f"{base}/health/liveliness")
return r.status_code == 200 # only meaningful when DATABASE_URL is configured at all Try / catch
except httpx.HTTPStatusError as e:
d = e.response.json().get("detail", {})
if e.response.status_code == 503 and isinstance(d, dict) and d.get("error") == "byok_auth_unavailable":
# DB is down or not configured: wait for DB health, then retry;
# if DATABASE_URL was never set, fix config instead of retrying
await wait_for_database_then_retry(payload)
return
raise Prevention
- Always set DATABASE_URL in any deployment that registers BYOK MCP servers.
- Include a DB health gate in startup probes so traffic only flows when prisma_client is initialized.
When it happens
Trigger: The proxy starts without DATABASE_URL (or the DB is still initializing) while a called MCP server has is_byok set; a DB outage mid-session causes the same failure on later calls.
Common situations: Dev/docker-compose setups running config.yaml without Postgres; promoting a config from an environment that had a DB into one that does not; migration windows.
Related errors
- Toolset '{toolset_name}' not found
- byok_auth_required
- MCP server for tool '{name}' is not available; refusing to d
- MCP server for tool '{original_tool_name}' is not available;
- Error creating mcp server: {e}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/2a17b241a7a42aa7.
Report an issue: GitHub.