BerriAI/litellm · error · Exception
Invalid hash key. Hash key={hashed_token}. Decrypted token={
Error message
Invalid hash key. Hash key={hashed_token}. Decrypted token={decrypted_token}. Error: {e} What it means
Raised when decrypting a UI session hash token: decrypt_value_helper succeeded, but json.loads(...) or UserAPIKeyAuth.model_validate(...) failed on the decrypted payload. The token was encrypted with the proxy's ui_hash_key; if the key changed between sessions or the payload is corrupt, decryption/validation produces garbage and this Exception names the hash key, the decrypted token, and the underlying parse error.
Source
Thrown at litellm/proxy/auth/auth_checks.py:2997
@staticmethod
def get_key_object_from_ui_hash_key(
hashed_token: str,
) -> UserAPIKeyAuth | None:
import json
from litellm.proxy.auth.user_api_key_auth import UserAPIKeyAuth
from litellm.proxy.common_utils.encrypt_decrypt_utils import (
decrypt_value_helper,
)
decrypted_token: Final = decrypt_value_helper(hashed_token, key="ui_hash_key", exception_type="debug")
if decrypted_token is None:
return None
try:
return UserAPIKeyAuth.model_validate(json.loads(decrypted_token))
except Exception as e:
raise Exception(f"Invalid hash key. Hash key={hashed_token}. Decrypted token={decrypted_token}. Error: {e}")
async def _fetch_key_object_from_db_with_reconnect(
hashed_token: str,
prisma_client: PrismaClient,
parent_otel_span: Span | None,
proxy_logging_obj: ProxyLogging | None,
) -> BaseModel | None:
"""
Fetch key object from DB and retry once if a DB connection error can be healed.
"""
try:
return await prisma_client.get_data(
token=hashed_token,
table_name="combined_view",
parent_otel_span=parent_otel_span,
proxy_logging_obj=proxy_logging_obj,
)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Re-authenticate through the UI/login flow to mint a fresh token under the current key — stale sessions are the most common cause
- Pin LITELLM_SALT_KEY (and any UI session encryption env) to a stable value across restarts/deployments so existing sessions remain valid
- If sessions must be invalidated wholesale after a key rotation, clear browser cookies/API clients of the old token
Example fix
# before (docker-compose, no pinned salt)
services:
litellm:
image: ghcr.io/berriai/litellm
# after
services:
litellm:
image: ghcr.io/berriai/litellm
environment:
LITELLM_SALT_KEY: "${LITELLM_SALT_KEY}" # stable across restarts Defensive patterns
Strategy: try-catch
Validate before calling
# before sending a stored UI token, sanity-check it still decrypts under this proxy
from litellm.proxy.auth.auth_checks import _get_ui_token_if_valid # conceptual
assert token.startswith("sk-") or len(token) > 40, "stale/corrupt session token" Try / catch
try:
user_auth = decode_hashed_token(hashed_token)
except Exception as e:
if "Invalid hash key" in str(e):
# session minted under a different LITELLM_SALT_KEY: force re-login
return RedirectResponse("/experimental/login/login")
raise Prevention
- Pin LITELLM_SALT_KEY to a stable secret across container restarts and deploys
- Treat salt-key rotation as a session invalidating event: clear stored tokens and re-authenticate
When it happens
Trigger: Presenting a UI session token minted under a different LITELLM_SALT_KEY/ui_hash_key than the running proxy uses (e.g. salt key rotated, container recreated without the env var), or a truncated/manually edited token in the Authorization header.
Common situations: Rotating or losing LITELLM_SALT_KEY so old UI sessions/cookies can no longer be validated; ephemeral Docker containers without a pinned salt key, invalidating sessions on each recreate; tokens persisted from a previous proxy version with a changed UserAPIKeyAuth schema.
Related errors
- User role is required for experimental UI login
- Cannot migrate covered tables: no salt key / master key is s
- Cannot route sensitive data without a session_id. Ensure the
- Sensitive data detected by {self.guardrail_name} (routing sk
- User role is required for CLI JWT login
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/164f0b072c2a993e.
Report an issue: GitHub.