{"record":{"id":"dc6385ebb4e23fbc","repo":"tiangolo/fastapi","slug":"invalid-x-token-header-dc6385","errorCode":null,"errorMessage":"Invalid X-Token header","messagePattern":"Invalid X-Token header","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"docs_src/app_testing/app_b_py310/main.py","lineNumber":23,"sourceCode":"\nfake_db = {\n    \"foo\": {\"id\": \"foo\", \"title\": \"Foo\", \"description\": \"There goes my hero\"},\n    \"bar\": {\"id\": \"bar\", \"title\": \"Bar\", \"description\": \"The bartenders\"},\n}\n\napp = FastAPI()\n\n\nclass Item(BaseModel):\n    id: str\n    title: str\n    description: str | None = None\n\n\n@app.get(\"/items/{item_id}\", response_model=Item)\nasync def read_main(item_id: str, x_token: str = Header()):\n    if x_token != fake_secret_token:\n        raise HTTPException(status_code=400, detail=\"Invalid X-Token header\")\n    if item_id not in fake_db:\n        raise HTTPException(status_code=404, detail=\"Item not found\")\n    return fake_db[item_id]\n\n\n@app.post(\"/items/\")\nasync def create_item(item: Item, x_token: str = Header()) -> Item:\n    if x_token != fake_secret_token:\n        raise HTTPException(status_code=400, detail=\"Invalid X-Token header\")\n    if item.id in fake_db:\n        raise HTTPException(status_code=409, detail=\"Item already exists\")\n    fake_db[item.id] = item.model_dump()\n    return item\n","sourceCodeStart":5,"sourceCodeEnd":37,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/docs_src/app_testing/app_b_py310/main.py#L5-L37","documentation":"Same logic as error 0 but in the non-Annotated (legacy default-parameter) variant of the file: GET /items/{item_id} raises 400 when the X-Token header != 'coneofsilence'. Functionally identical; only the header-injection style differs (x_token: str = Header() vs Annotated[str, Header()]).","triggerScenarios":"GET /items/{item_id} with an X-Token header that is not exactly 'coneofsilence'.","commonSituations":"Client was written against the Annotated variant and reused on this variant; token drift; header stripped by a proxy.","solutions":["Send X-Token: coneofsilence.","Keep a single source of truth for the token across all variants of the app.","Prefer the Annotated form (the py310 file is the older style) to stay consistent with current FastAPI docs."],"exampleFix":"// before\nGET /items/foo   X-Token: anything\n// after\nGET /items/foo   X-Token: coneofsilence","handlingStrategy":"validation","validationCode":"import httpx\nresp = httpx.get('http://localhost:8000/items/foo', headers={'X-Token': 'coneofsilence'})","typeGuard":"def is_valid_x_token(value: object) -> bool:\n    return isinstance(value, str) and value == 'coneofsilence'","tryCatchPattern":null,"preventionTips":["Keep a single token constant shared across file variants.","Prefer the Annotated variant going forward.","Add a client middleware that injects the header automatically."],"tags":["fastapi","authentication","header","httpexception","app-testing"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}