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

  1. Send header X-Token: fake-super-secret-token (exact value) on every request.
  2. 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.
  3. 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

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)