oobabooga/textgen · error · HTTPException
Unauthorized
Error message
Unauthorized
What it means
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.
Source
Thrown at modules/api/script.py:71
ModelListResponse,
TokenCountResponse,
to_dict
)
async def _wait_for_disconnect(request: Request, stop_event: threading.Event):
"""Block until the client disconnects, then signal the stop_event."""
while True:
message = await request.receive()
if message["type"] == "http.disconnect":
stop_event.set()
return
def verify_api_key(authorization: str = Header(None)) -> None:
expected_api_key = shared.args.api_key
if expected_api_key and (authorization is None or authorization != f"Bearer {expected_api_key}"):
raise HTTPException(status_code=401, detail="Unauthorized")
def verify_admin_key(authorization: str = Header(None)) -> None:
expected_api_key = shared.args.admin_key
if expected_api_key and (authorization is None or authorization != f"Bearer {expected_api_key}"):
raise HTTPException(status_code=401, detail="Unauthorized")
def verify_anthropic_key(x_api_key: str = Header(None, alias="x-api-key")) -> None:
expected_api_key = shared.args.api_key
if expected_api_key and (x_api_key is None or x_api_key != expected_api_key):
raise HTTPException(status_code=401, detail="Unauthorized")
class AnthropicError(Exception):
def __init__(self, message: str, error_type: str = "invalid_request_error", status_code: int = 400):
self.message = message
self.error_type = error_typeView on GitHub (pinned to ed888c71f2)
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.
Example fix
# before
import requests
requests.post('http://127.0.0.1:5000/v1/chat/completions', json={...}) # 401
# after
requests.post(
'http://127.0.0.1:5000/v1/chat/completions',
headers={'Authorization': 'Bearer sk-my-key'},
json={...},
) Defensive patterns
Strategy: validation
Validate before calling
import os
def auth_headers(api_key: str | None) -> dict:
if not api_key:
raise ValueError('API key required: server was started with --api-key')
return {'Authorization': f'Bearer {api_key}'}
Try / catch
# In OpenAI SDK clients, catch 401 explicitly and fail fast with a clear message
from openai import AuthenticationError
try:
client.chat.completions.create(...)
except AuthenticationError:
raise RuntimeError('Check --api-key on the server and the api_key passed to the client') from None
Prevention
- 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.
When it happens
Trigger: 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').
Common situations: 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.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
AI-assisted analysis of oobabooga/textgen@ed888c71f2 (2026-08-15).
Data as JSON: /api/errors/c87d405804eff8b8.
Report an issue: GitHub.