BerriAI/litellm · critical · HTTPException

Invalid bearer token

Error message

Invalid bearer token

What it means

Same pre-flight guard as job creation, but on the cancel path: cancel_fine_tuning_job resolves an OpenAI client via get_openai_client(), and if it returns None (no api_key argument, no OPENAI_API_KEY env/secret, no custom client), this ValueError is raised before any API call. It signals missing credentials, not an upstream failure.

Source

Thrown at cookbook/mock_guardrail_server/mock_bedrock_guardrail_server.py:197

            detail="Missing Authorization header",
            headers={"WWW-Authenticate": "Bearer"},
        )

    # Check if it's a Bearer token
    parts = authorization.split()
    print(f"parts: {parts}")
    if len(parts) != 2 or parts[0].lower() != "bearer":
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid Authorization header format. Expected: Bearer <token>",
            headers={"WWW-Authenticate": "Bearer"},
        )

    token = parts[1]

    # Verify token
    if token != GUARDRAIL_CONFIG.bearer_token:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Invalid bearer token",
        )

    return token


# ============================================================================
# Guardrail Logic
# ============================================================================


def check_blocked_words(text: str) -> Optional[WordPolicy]:
    """Check if text contains blocked words"""
    found_words = []
    text_lower = text.lower()

    for word in GUARDRAIL_CONFIG.blocked_words:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Export OPENAI_API_KEY in the environment where cancellation runs.
  2. Or pass api_key=... explicitly to cancel_fine_tuning_job.
  3. Or pass a constructed OpenAI client via client=.

Example fix

# before
litellm.cancel_fine_tuning_job(fine_tuning_job_id="ftjob-abc")

# after
litellm.cancel_fine_tuning_job(fine_tuning_job_id="ftjob-abc", api_key=os.environ["OPENAI_API_KEY"])
Defensive patterns

Strategy: validation

Validate before calling

import os

def can_cancel_jobs(api_key: str | None) -> bool:
    return bool(api_key or os.environ.get("OPENAI_API_KEY"))

Try / catch

try:
    litellm.cancel_fine_tuning_job(fine_tuning_job_id=jid)
except ValueError as e:
    if "not initialized" in str(e):
        litellm.cancel_fine_tuning_job(fine_tuning_job_id=jid, api_key=os.environ["OPENAI_API_KEY"])
    else:
        raise

Prevention

When it happens

Trigger: Calling litellm.cancel_fine_tuning_job(fine_tuning_job_id=...) without api_key, client, or OPENAI_API_KEY configured anywhere in the lookup chain.

Common situations: Long-running training orchestration scripts that create jobs in one process (with key set) and cancel from another (cron/CI) without the env var; key rotation removing the env var between create and cancel.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/0dcf9e406cf51e05. Report an issue: GitHub.