tiangolo/fastapi · error · HTTPException

X-Token header invalid

Error message

X-Token header invalid

What it means

Raised (400) by the get_token_header dependency used app-wide on the /items APIRouter in the 'bigger applications' example. Any request to a route mounted under that router must carry X-Token equal to 'fake-super-secret-token', or this dependency short-circuits the request before the route body runs. Because it is declared in router dependencies=[Depends(get_token_header)], it applies to every route in the router uniformly.

Solutions

  1. Send X-Token: fake-super-secret-token for any /items/* request.
  2. Note this token differs from other tutorials' tokens; do not reuse headers across examples.
  3. Extract the expected token to a shared config/secret manager.

Example fix

// before
GET /items/   (no X-Token)
// after
GET /items/   X-Token: fake-super-secret-token
Defensive patterns

Strategy: validation

Validate before calling

import httpx
TOKEN = 'fake-super-secret-token'
resp = httpx.get('http://localhost:8000/items/', headers={'X-Token': TOKEN})

Type guard

def is_valid_router_token(value: object) -> bool:
    return isinstance(value, str) and value == 'fake-super-secret-token'

Prevention

When it happens

Trigger: Any GET/PUT on /items/... without X-Token: fake-super-secret-token. The dependency is attached at router level, so even read_items and update_item are guarded.

Common situations: The token is a different literal than the app_testing example ('fake-super-secret-token' vs 'coneofsilence'), so developers who copy headers between examples get 400. Router-level guards are easy to forget when adding a new client.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/679d3df39de61279. Report an issue: GitHub.

Appendix: source

Thrown at docs_src/bigger_applications/app_an_py310/dependencies.py:8

from typing import Annotated

from fastapi import Header, HTTPException


async def get_token_header(x_token: Annotated[str, Header()]):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")


async def get_query_token(token: str):
    if token != "jessica":
        raise HTTPException(status_code=400, detail="No Jessica token provided")

View on GitHub (pinned to 3e8d1526d8)