{"record":{"id":"c87d405804eff8b8","repo":"oobabooga/textgen","slug":"unauthorized","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"modules/api/script.py","lineNumber":71,"sourceCode":"    ModelListResponse,\n    TokenCountResponse,\n    to_dict\n)\n\n\nasync def _wait_for_disconnect(request: Request, stop_event: threading.Event):\n    \"\"\"Block until the client disconnects, then signal the stop_event.\"\"\"\n    while True:\n        message = await request.receive()\n        if message[\"type\"] == \"http.disconnect\":\n            stop_event.set()\n            return\n\n\ndef verify_api_key(authorization: str = Header(None)) -> None:\n    expected_api_key = shared.args.api_key\n    if expected_api_key and (authorization is None or authorization != f\"Bearer {expected_api_key}\"):\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\ndef verify_admin_key(authorization: str = Header(None)) -> None:\n    expected_api_key = shared.args.admin_key\n    if expected_api_key and (authorization is None or authorization != f\"Bearer {expected_api_key}\"):\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\ndef verify_anthropic_key(x_api_key: str = Header(None, alias=\"x-api-key\")) -> None:\n    expected_api_key = shared.args.api_key\n    if expected_api_key and (x_api_key is None or x_api_key != expected_api_key):\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass AnthropicError(Exception):\n    def __init__(self, message: str, error_type: str = \"invalid_request_error\", status_code: int = 400):\n        self.message = message\n        self.error_type = error_type","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/oobabooga/textgen/blob/ed888c71f221df552750e1834b3654abab8ae345/modules/api/script.py#L53-L89","documentation":"Raised by the FastAPI dependency verify_api_key (modules/api/script.py:71) on every OpenAI-compatible /v1 endpoint. When the server was started with --api-key, each request must carry an Authorization header exactly equal to 'Bearer <that key>'. If no --api-key was set at startup, the check passes silently.","triggerScenarios":"Calling any /v1/* route (chat/completions, completions, embeddings, models, token encode/decode, etc.) with a missing Authorization header, a bare key without the 'Bearer ' prefix, the wrong key, or a malformed scheme (e.g. 'bearer' lowercase vs 'Bearer').","commonSituations":"Client copied an OpenAI SDK example but forgot to set api_key; key typed with whitespace/newline; using the admin key instead of the API key; server restarted with a different --api-key than the one baked into the client; proxy stripping the Authorization header.","solutions":["Send 'Authorization: Bearer <your --api-key value>' on every /v1 request (OpenAI SDK: openai.OpenAI(base_url='...:/v1', api_key='<key>')).","Confirm the server was actually started with --api-key; if none is set the endpoint is open and no header is needed.","Check for typos/whitespace/case in the key and remember the scheme ('Bearer ') is case-sensitive.","If a reverse proxy sits in front, verify it forwards the Authorization header."],"exampleFix":"# before\nimport requests\nrequests.post('http://127.0.0.1:5000/v1/chat/completions', json={...})  # 401\n\n# after\nrequests.post(\n    'http://127.0.0.1:5000/v1/chat/completions',\n    headers={'Authorization': 'Bearer sk-my-key'},\n    json={...},\n)","handlingStrategy":"validation","validationCode":"import os\n\ndef auth_headers(api_key: str | None) -> dict:\n    if not api_key:\n        raise ValueError('API key required: server was started with --api-key')\n    return {'Authorization': f'Bearer {api_key}'}\n","typeGuard":null,"tryCatchPattern":"# In OpenAI SDK clients, catch 401 explicitly and fail fast with a clear message\nfrom openai import AuthenticationError\ntry:\n    client.chat.completions.create(...)\nexcept AuthenticationError:\n    raise RuntimeError('Check --api-key on the server and the api_key passed to the client') from None\n","preventionTips":["Store the --api-key in an env var and inject it into both server flags and client config from one source.","Write an integration smoke test that calls GET /v1/models with auth; run it before deploying clients.","Never assume admin and API keys are interchangeable; keep them in separate config fields."],"tags":["auth","http","api","fastapi","openai-compatible"],"backgroundTag":null,"analyzedSha":"ed888c71f221df552750e1834b3654abab8ae345","analyzedAt":"2026-08-15T05:24:21.000Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}