tiangolo/fastapi · error · HTTPException
X-Token header invalid
Error message
X-Token header invalid
What it means
HTTPException (400) raised by the global dependency verify_token, registered on the FastAPI app via dependencies=[Depends(verify_token), ...]. It reads the X-Token header and compares to a hard-coded secret 'fake-super-secret-token'. Because it is an app-level dependency, EVERY route (e.g. /items/ and /users/) requires the header. FastAPI runs these before the path operation, so a bad/missing token fails every request with 400.
Solutions
- Send header X-Token: fake-super-secret-token (exact value) on every request.
- Double-check header name casing/hyphenation — FastAPI maps x_token parameter to the 'X-Token' header; 'X-Token' and 'x-token' are equivalent but other spellings are not.
- If the token is real, source it from configuration/env rather than hard-coding, and ensure the client uses the same source.
Example fix
// before curl http://localhost:8000/items/ // after curl -H 'X-Token: fake-super-secret-token' -H 'X-Key: fake-super-secret-key' http://localhost:8000/items/
Defensive patterns
Strategy: validation
Validate before calling
headers = {'X-Token': os.environ.get('X_TOKEN', 'fake-super-secret-token'), 'X-Key': 'fake-super-secret-key'}
assert headers['X-Token'], 'X-Token required' Type guard
def has_valid_x_token(headers: dict) -> bool:
return headers.get('X-Token') == 'fake-super-secret-token' Try / catch
resp = requests.get('http://localhost:8000/items/', headers=headers)
if resp.status_code == 400 and 'X-Token' in resp.text:
print('bad/missing X-Token') Prevention
- Send both X-Token and X-Key on every request.
- Source secrets from env/config, not literals.
- Verify header name mapping (x_token -> X-Token).
When it happens
Trigger: Any request to /items/ or /users/ (or any route on this app) without header 'X-Token: fake-super-secret-token', or with a wrong value. Missing header triggers FastAPI's own 422 (missing required header) before this 400; a present-but-wrong value triggers this 400.
Common situations: Global API-key/header gateways. Developers hit this when their client omits the X-Token header, sends it under a different name (case or hyphenation), or rotates the secret on the server but not the client.
Related errors
AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11).
Data as JSON: /api/errors/cebdd7177513624a.
Report an issue: GitHub.
Appendix: source
Thrown at docs_src/dependencies/tutorial012_an_py310.py:8
from typing import Annotated
from fastapi import Depends, FastAPI, Header, HTTPException
async def verify_token(x_token: Annotated[str, Header()]):
if x_token != "fake-super-secret-token":
raise HTTPException(status_code=400, detail="X-Token header invalid")
async def verify_key(x_key: Annotated[str, Header()]):
if x_key != "fake-super-secret-key":
raise HTTPException(status_code=400, detail="X-Key header invalid")
return x_key
app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])
@app.get("/items/")
async def read_items():
return [{"item": "Portal Gun"}, {"item": "Plumbus"}]
@app.get("/users/")
async def read_users():View on GitHub (pinned to 3e8d1526d8)