tiangolo/fastapi · error · HTTPException
Invalid X-Token header
Error message
Invalid X-Token header
What it means
This HTTPException is raised by the GET /items/{item_id} handler in the app-testing example when the incoming X-Token request header does not equal the hardcoded secret token ("coneofsilence"). FastAPI uses HTTPException to short-circuit the request and return a structured JSON error response with HTTP status 400 instead of running the rest of the handler. It is a simple bearer-style guard meant to demonstrate authentication on a protected read endpoint.
Source
Thrown at docs_src/app_testing/app_b_an_py310/main.py:25
fake_db = {
"foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},
"bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
}
app = FastAPI()
class Item(BaseModel):
id: str
title: str
description: str | None = None
@app.get("/items/{item_id}", response_model=Item)
async def read_main(item_id: str, x_token: Annotated[str, Header()]):
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item_id not in fake_db:
raise HTTPException(status_code=404, detail="Item not found")
return fake_db[item_id]
@app.post("/items/")
async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item:
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item.id in fake_db:
raise HTTPException(status_code=409, detail="Item already exists")
fake_db[item.id] = item.model_dump()
return item
View on GitHub (pinned to 42a41db11f)
Solutions
- Send the header X-Token: coneofsilence on every GET /items/{item_id} request.
- If using TestClient, pass headers={"X-Token": "coneofsilence"} in the call.
- Replace the hardcoded token with a value loaded from settings/env so client and server agree.
- Confirm the header name casing/underscore: FastAPI maps x_token to the X-Token header.
Example fix
# before
client.get("/items/foo")
# after
client.get("/items/foo", headers={"X-Token": "coneofsilence"}) Defensive patterns
Strategy: validation
Validate before calling
# Validate the token is present and correct before sending
EXPECTED_TOKEN = "coneofsilence"
assert EXPECTED_TOKEN, "X-Token not configured"
headers = {"X-Token": EXPECTED_TOKEN} if EXPECTED_TOKEN else {} Type guard
def has_valid_token(token: str | None) -> bool:
return token is not None and token == "coneofsilence" Prevention
- Store the token in an env var and load it once at startup.
- Wrap all requests in a helper that injects the X-Token header.
- In tests, assert the header is set before each call.
When it happens
Trigger: A GET /items/{item_id} request where the X-Token header is absent, empty, or any value other than "coneofsilence" (e.g. curl http://host/items/foo without -H "X-Token: coneofsilence").
Common situations: Test clients (httpx/TestClient) that forget to attach the header; frontend code that drops headers on a refresh; copying an example with a placeholder token; deploying with a token that differs from the client's configured value.
Related errors
- Invalid X-Token header
- X-Token header invalid
- X-Token header invalid
- X-Key header invalid
- X-Token header invalid
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/23ef81dae03fef0d.json.
Report an issue: GitHub.