BerriAI/litellm · error · HTTPException
Invalid authorization header format. Expected 'Bearer <token
Error message
Invalid authorization header format. Expected 'Bearer <token>'
What it means
The async-client type guard on the cancel path: with _is_async=True, cancel_fine_tuning_job requires an AsyncOpenAI or AsyncAzureOpenAI client. If a synchronous client was resolved or passed, awaiting the cancel call would fail at runtime, so this ValueError raises early with an explicit message. Purely a local client-type mismatch.
Source
Thrown at cookbook/mock_prompt_management_server/mock_prompt_management_server.py:181
def verify_api_key(authorization: Optional[str] = Header(None)) -> bool:
"""
Verify the API key from the Authorization header.
Args:
authorization: Authorization header (Bearer token)
Returns:
True if valid, raises HTTPException if invalid
"""
if authorization is None:
# Allow requests without authentication for testing
return True
# Extract token from "Bearer <token>"
if not authorization.startswith("Bearer "):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authorization header format. Expected 'Bearer <token>'",
)
token = authorization.replace("Bearer ", "").strip()
if token not in VALID_API_TOKENS:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API key",
)
return True
@app.get("/beta/litellm_prompt_management", response_model=PromptResponse)
async def get_prompt(
prompt_id: str = Query(..., description="The ID of the prompt to fetch"),View on GitHub (pinned to 6c2dcb801b)
Solutions
- Construct and pass AsyncOpenAI(api_key=...) for async cancellation.
- Or omit the custom client and let litellm create the async client from the environment key.
- Or keep cancellation synchronous with cancel_fine_tuning_job().
Example fix
# before await litellm.acancel_fine_tuning_job(fine_tuning_job_id="ftjob-abc", client=OpenAI()) # after await litellm.acancel_fine_tuning_job(fine_tuning_job_id="ftjob-abc", client=AsyncOpenAI())
Defensive patterns
Strategy: type-guard
Validate before calling
from openai import AsyncOpenAI
def assert_async_client_for_cancel(client: object) -> None:
assert isinstance(client, AsyncOpenAI), f"expected AsyncOpenAI, got {type(client).__name__}" Type guard
from openai import AsyncOpenAI, AsyncAzureOpenAI
def is_usable_async_client(client: object) -> bool:
return isinstance(client, (AsyncOpenAI, AsyncAzureOpenAI)) Try / catch
try:
await litellm.acancel_fine_tuning_job(fine_tuning_job_id=jid, client=client)
except ValueError as e:
if "AsyncOpenAI" in str(e):
from openai import AsyncOpenAI
await litellm.acancel_fine_tuning_job(fine_tuning_job_id=jid, client=AsyncOpenAI())
else:
raise Prevention
- Keep one client factory keyed by sync/async so cancellation daemons always get async clients.
- Add isinstance asserts at wiring time to fail at startup, not at cancel time.
When it happens
Trigger: Calling the async cancel path (await litellm.acancel_fine_tuning_job(...)) while passing a sync OpenAI() client, or letting the handler resolve a sync client for an async operation.
Common situations: Async orchestration daemons reusing a sync client singleton; refactoring sync job-management code to asyncio without updating client construction; mixing sync creation and async cancellation in the same module.
Related errors
- Invalid Authorization header format. Expected: Bearer <token
- Prompt '{prompt_id}' not found. Available prompts: {list(PRO
- Prompt '{prompt.prompt_id}' already exists
- Failed to connect to Braintrust API: {str(e)}
- Missing Authorization header
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/620069d36817716d.
Report an issue: GitHub.