BerriAI/litellm · error · Exception

No api key passed in.

Error message

No api key passed in.

What it means

Raised when the proxy has a master key configured (making authentication mandatory) but the request contained no API key at all — no usable `Authorization: Bearer` header, no `x-litellm-api-key` header, and no key elsewhere. It is a plain `Exception`, so the response status depends on the proxy's exception wrapping (usually surfaced as an auth failure / 500-shaped error, not a clean 401).

Source

Thrown at litellm/proxy/auth/user_api_key_auth.py:1489

            )
            if isinstance(response, str):
                api_key = response
            elif isinstance(response, UserAPIKeyAuth):
                return response
        if master_key is None:
            if isinstance(api_key, str):
                return UserAPIKeyAuth(
                    api_key=api_key,
                    user_role=LitellmUserRoles.INTERNAL_USER,
                    parent_otel_span=parent_otel_span,
                )
            else:
                return UserAPIKeyAuth(
                    user_role=LitellmUserRoles.INTERNAL_USER,
                    parent_otel_span=parent_otel_span,
                )
        elif api_key is None:  # only require api key if master key is set
            raise Exception("No api key passed in.")
        elif api_key == "":
            # missing 'Bearer ' prefix
            raise Exception("Malformed API Key passed in. Ensure Key has `Bearer ` prefix.")

        if route == "/user/auth":
            if general_settings.get("allow_user_auth", False) is True:
                return UserAPIKeyAuth()
            else:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="'allow_user_auth' not set or set to False",
                )

        ## Check END-USER OBJECT
        _end_user_object = None
        end_user_params: Final = {}

        raw_end_user_id: Final = get_end_user_id_from_request_body(request_data, _safe_get_request_headers(request))

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Send the key: `Authorization: Bearer <key>` or `x-litellm-api-key: <key>` where key is the master key or a virtual key
  2. Verify the client actually attaches the key — e.g. `OpenAI(base_url=..., api_key=os.environ['PROXY_KEY'])` with the var truly set
  3. For probes, point them at an unauthenticated health route instead of removing auth on business routes

Example fix

# before
client = OpenAI(base_url="http://proxy:4000", api_key=os.getenv("PROXY_KEY"))  # var unset -> no header

# after
key = os.environ["PROXY_KEY"]  # KeyError at startup, not 500 per request
client = OpenAI(base_url="http://proxy:4000", api_key=key)
Defensive patterns

Strategy: validation

Validate before calling

key = os.environ.get("PROXY_KEY")
if key is None:
    raise RuntimeError("PROXY_KEY not set — refusing to call proxy without credentials")
client = OpenAI(base_url=PROXY, api_key=key)

Type guard

def has_api_key(client) -> bool:
    return bool(getattr(client, "api_key", None))

Try / catch

try:
    client.chat.completions.create(...)
except Exception as e:
    if "No api key passed in" in str(e):
        raise RuntimeError("missing Authorization header — check client credentials") from e
    raise

Prevention

When it happens

Trigger: `master_key` is set and a client calls any protected route with no Authorization header at all, e.g. `curl http://proxy:4000/v1/chat/completions -d '{...}'`, or an OpenAI SDK client built with an unset `api_key` so no header is attached.

Common situations: Scripts that worked before a master key was added; env var holding the key never exported so the client silently sends nothing; health checks or monitoring probes hitting protected endpoints; Kubernetes readiness probes not sending credentials.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/fe3a6fdea63f3996. Report an issue: GitHub.