{"record":{"id":"cb991a7660a47323","repo":"BerriAI/litellm","slug":"key-is-blocked-update-via-key-unblock-if-you-r","errorCode":null,"errorMessage":"Key is blocked. Update via `/key/unblock` if you're an admin.","messagePattern":"Key is blocked\\. Update via `/key/unblock` if you're an admin\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/proxy/auth/user_api_key_auth.py","lineNumber":1785,"sourceCode":"        user_obj: LiteLLM_UserTable | None = None\n        valid_token_dict: dict = {}\n        if valid_token is not None:\n            # Got Valid Token from Cache, DB\n            # Run checks for\n            # 1. If token can call model\n            ## 1a. If token can call fallback models (if client-side fallbacks given)\n            # 2. If user_id for this token is in budget\n            # 3. If the user spend within their own team is within budget\n            # 4. If 'user' passed to /chat/completions, /embeddings endpoint is in budget\n            # 5. If token is expired\n            # 6. If token spend is under Budget for the token\n            # 7. If token spend per model is under budget per model\n            # 8. If token spend is under team budget\n            # 9. If team spend is under team budget\n\n            ## base case ## key is disabled\n            if valid_token.blocked is True:\n                raise Exception(\"Key is blocked. Update via `/key/unblock` if you're an admin.\")\n            await _enforce_key_and_fallback_model_access(\n                valid_token=valid_token,\n                request_data=request_data,\n                route=route,\n                request=request,\n                llm_model_list=llm_model_list,\n                llm_router=llm_router,\n            )\n\n            # Check 2. If user_id for this token is in budget - done in common_checks()\n            if valid_token.user_id is not None:\n                try:\n                    with tracer.trace(\"litellm.proxy.auth.get_user_object\"):\n                        user_obj = await get_user_object(\n                            user_id=valid_token.user_id,\n                            prisma_client=prisma_client,\n                            user_api_key_cache=user_api_key_cache,\n                            user_id_upsert=False,","sourceCodeStart":1767,"sourceCodeEnd":1803,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/auth/user_api_key_auth.py#L1767-L1803","documentation":"Hard block on the `blocked` flag of the token: an admin (or a blocking policy) previously disabled this key via `/key/block`, so every request using it fails this base-case check before budgets, models, or teams are even evaluated. Unblocking is deliberately admin-only via `/key/unblock`.","triggerScenarios":"Using a key after `POST /key/block {\"key\": ...}` (e.g. quarantine of a leaked key, offboarding a contractor); keys auto-blocked by incident response; leftover creds in a service after security rotation.","commonSituations":"Leaked-key response blocking the compromised key while the leaking service keeps retrying; offboarding a user but their CI job still runs; blocked key alias reused by another team unaware of the block; testing whether a key works after a security event.","solutions":["If the block was corrective and is resolved, an admin calls `POST /key/unblock` with the key (or its hash)","Otherwise stop using the key: issue a replacement via `/key/generate` and update the client","Audit `/key/info` (admin) to see the blocked state and who/what blocked it before re-enabling"],"exampleFix":"# before: service keeps using blocked key -> exception on every call\nclient = OpenAI(base_url=..., api_key=blocked_key)\n\n# after: admin restores\nadmin.post(\"/key/unblock\", json={\"key\": key_hash})\n# or rotate: new_key = admin.post(\"/key/generate\", json={...}).json()[\"key\"]","handlingStrategy":"try-catch","validationCode":"# admin pre-flight before a critical run\ninfo = admin.post(\"/key/info\", json={\"keys\": [hash_key(key)]}).json()\nif info[\"info\"][0].get(\"blocked\"):\n    admin.post(\"/key/unblock\", json={\"key\": hash_key(key)})  # if legitimately restorable","typeGuard":null,"tryCatchPattern":"try:\n    resp = client.chat.completions.create(...)\nexcept Exception as e:\n    if \"Key is blocked\" in str(e):\n        notify_admin(f\"key {alias} blocked — unblock via /key/unblock or rotate\")\n        raise KeyBlocked(alias) from e\n    raise","preventionTips":["After any leak response, rotate clients off blocked keys instead of retrying","Alert on blocked-key errors so owners learn the key needs replacement","Document the /key/unblock runbook for admins"],"tags":["auth","blocked-key","admin","key-management","litellm"],"backgroundTag":"api-key-blocked","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}