BerriAI/litellm · error · ProxyException
not_found_error
not_found_error
Error message
Key not found in database
What it means
GET /key/info looked up the (hashed) key token via find_unique on the verification-token table and got no row. The key may have been deleted, expired keys still return rows (expiry is checked elsewhere), so 'not found' specifically means no such token exists in the DB — including when you passed the raw token while the DB stores hashes handled by _hash_token_if_needed (that case is normalized), so the usual causes are deletion or a wrong/foreign key value. Returned as a typed ProxyException with code not_found_error and HTTP 404.
Source
Thrown at litellm/proxy/management_endpoints/key_management_endpoints.py:3675
from litellm.proxy.proxy_server import prisma_client, user_api_key_cache
try:
if prisma_client is None:
raise Exception(
"Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys"
)
# default to using Auth token if no key is passed in
key = key or user_api_key_dict.api_key
hashed_key: str | None = key
if key is not None:
hashed_key = _hash_token_if_needed(token=key)
key_info = await VerificationTokenRepository(prisma_client).table.find_unique(
where={"token": hashed_key},
include={"litellm_budget_table": True},
)
if key_info is None:
raise ProxyException(
message="Key not found in database",
type=ProxyErrorTypes.not_found_error,
param="key",
code=status.HTTP_404_NOT_FOUND,
)
if (
await _can_user_query_key_info(
user_api_key_dict=user_api_key_dict,
key=key,
key_info=key_info,
)
is not True
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"You are not allowed to access this key's info. Your role={user_api_key_dict.user_role}",
)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Re-list live keys (GET /key/info without key for your own key, or admin batch /v2/key/info) and use a current token.
- If querying by human-friendly name, pass key_alias via /v2/key/info instead of the raw token value.
- Confirm you're hitting the right proxy host/database for that key.
Example fix
# before
info = client.get("/key/info", params={"key": "sk-copied-wrong"})
# after
resp = client.post("/v2/key/info", json={"key_aliases": ["my-alias"]})
if resp.status_code == 404:
log.warning("key no longer exists; refresh key list") Defensive patterns
Strategy: try-catch
Validate before calling
def key_exists(client, key: str) -> bool:
resp = client.get("/key/info", params={"key": key})
return resp.status_code == 200 Try / catch
try:
info = client.get("/key/info", params={"key": key})
info.raise_for_status()
except HTTPError as e:
if e.response.status_code == 404:
evict_from_cache(key) # deleted/rotated elsewhere
return None
raise Prevention
- Treat 404 on key info as an expected lifecycle event: evict from caches, don't retry.
- Prefer key_alias lookups over raw tokens in dashboards so rotation doesn't break queries.
- Pin clients to one environment's proxy URL to avoid querying keys that live in another DB.
When it happens
Trigger: GET /key/info?key=sk-typo or a key deleted via /key/delete; querying with an alias string instead of the token; querying a key generated on a different proxy/database.
Common situations: Dashboard caching a key list after an admin purged keys; copy-paste truncating the token; pointing a client at the wrong environment's proxy; key rotated by an async job between listing and lookup.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- No keys found for team {data.team_id}
- Key not found in team {data.team_id}
- Skill not found: {skill_id}
- Plugin '{plugin_name}' not found
- User doesn't exist in db. 'user_id'={user_id}. Create user v
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/aabb13f6452cc6c8.
Report an issue: GitHub.