BerriAI/litellm · error · ProxyException
Key health check failed: {e}
Error message
Key health check failed: {e} What it means
Catch-all wrapper around the key health-check endpoint (GET /key/health): any exception raised while building the health report — DB reads, decryption of key metadata, logging-callback probes — is re-raised as a 500 ProxyException whose message embeds the original error text. The proxy_logging/verbose logs carry the full traceback; the client only sees this summary.
Source
Thrown at litellm/proxy/management_endpoints/key_management_endpoints.py:6493
)
# Check if logging is configured in metadata
if key_metadata and "logging" in key_metadata:
logging_statuses: Final = await test_key_logging(
user_api_key_dict=user_api_key_dict,
request=request,
key_logging=decrypt_callback_vars(key_metadata)["logging"],
)
health_status["logging_callbacks"] = logging_statuses
# Check if any logging callback is unhealthy
if logging_statuses.get("status") == "unhealthy":
health_status["key"] = "unhealthy"
return KeyHealthResponse(**health_status)
except Exception as e:
raise ProxyException(
message=f"Key health check failed: {e}",
type=ProxyErrorTypes.internal_server_error,
param=getattr(e, "param", "None"),
code=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
async def _can_user_query_key_info(
user_api_key_dict: UserAPIKeyAuth,
key: str | None,
key_info: LiteLLM_VerificationToken,
) -> bool:
"""
Helper to check if the user has access to the key's info
"""
if (
(
user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN.valueView on GitHub (pinned to 77b7c6c40c)
Solutions
- Read the nested message after the colon — it names the actual failure (e.g. 'callback_name is required in key_logging' or a Prisma error)
- Check the proxy server logs at ERROR level for the full traceback of the same request
- If the cause is key metadata, regenerate or update the key so its 'logging'/'metadata' JSON is well-formed
- Fix the underlying dependency (DB connectivity, LITELLM_SALT_KEY, custom callback) and re-run the health check
Defensive patterns
Strategy: try-catch
Try / catch
try:
r = await client.get('/key/health', params={'key': tok})
r.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 500:
inner = e.response.json().get('error', '')
if 'callback_name' in inner:
fix_key_logging_metadata(tok) # data problem, fixable client-side
else:
page_on_caller('key health degraded', inner) # infra problem; check proxy logs
raise Prevention
- Treat /key/health as advisory: alert on failures but keep request serving independent of it
- Keep key metadata small and machine-generated to avoid malformed 'logging' entries
- Correlate the 500 with server logs via request id before acting on the summarized message
When it happens
Trigger: A malformed 'logging' entry in key metadata that blows up during callback status checks; database connectivity blips while fetching the key row; decryption failures on metadata encrypted with a different LITELLM_SALT_KEY; bugs in custom logging callbacks invoked during the probe request.
Common situations: Rotating the salt/encryption key after keys were created; custom callback classes that raise on init; transient Postgres restarts; upgrading LiteLLM versions where metadata schema changed.
Related errors
- Failed to generate marketplace: {e}
- Registration failed: {e}
- str(e)
- 503
- Only proxy admins can set `allowed_passthrough_routes` on a
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/c573e996a17f3611.
Report an issue: GitHub.