{"record":{"id":"80510d035c7125bb","repo":"tiangolo/fastapi","slug":"x-key-header-invalid-80510d","errorCode":null,"errorMessage":"X-Key header invalid","messagePattern":"X-Key header invalid","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"docs_src/dependencies/tutorial012_py310.py","lineNumber":11,"sourceCode":"from fastapi import Depends, FastAPI, Header, HTTPException\n\n\nasync def verify_token(x_token: str = Header()):\n    if x_token != \"fake-super-secret-token\":\n        raise HTTPException(status_code=400, detail=\"X-Token header invalid\")\n\n\nasync def verify_key(x_key: str = Header()):\n    if x_key != \"fake-super-secret-key\":\n        raise HTTPException(status_code=400, detail=\"X-Key header invalid\")\n    return x_key\n\n\napp = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])\n\n\n@app.get(\"/items/\")\nasync def read_items():\n    return [{\"item\": \"Portal Gun\"}, {\"item\": \"Plumbus\"}]\n\n\n@app.get(\"/users/\")\nasync def read_users():\n    return [{\"username\": \"Rick\"}, {\"username\": \"Morty\"}]\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/docs_src/dependencies/tutorial012_py310.py#L1-L26","documentation":"Identical to error 27 but in tutorial012_py310.py (non-Annotated form). Global dependency verify_key enforces X-Key == 'fake-super-secret-key', raising HTTPException(400) on mismatch. Applies to every route.","triggerScenarios":"Any request with a valid X-Token but a missing or wrong X-Key header. Missing header -> 422; present-but-wrong -> 400.","commonSituations":"Forgetting the second of two required headers, or sending a stale key after rotation.","solutions":["Send X-Key: fake-super-secret-key alongside a valid X-Token.","Confirm both headers are configured identically across server and client.","Source both secrets from the same configuration store."],"exampleFix":"// before\nasync def verify_key(x_key: str = Header()):\n    if x_key != \"fake-super-secret-key\":\n        raise HTTPException(status_code=400, detail=\"X-Key header invalid\")\n// after\nEXPECTED_KEY = os.environ[\"EXPECTED_X_KEY\"]\nasync def verify_key(x_key: str = Header()):\n    if x_key != EXPECTED_KEY:\n        raise HTTPException(status_code=400, detail=\"X-Key header invalid\")","handlingStrategy":"validation","validationCode":"headers = {'X-Key': os.environ['X_KEY']}\nassert headers['X-Key'] == 'fake-super-secret-key'","typeGuard":"def has_valid_x_key(headers: dict) -> bool:\n    return headers.get('X-Key') == 'fake-super-secret-key'","tryCatchPattern":"resp = requests.get(url, headers=headers)\nif resp.status_code == 400:\n    print('X-Key invalid:', resp.json()['detail'])","preventionTips":["Send X-Key alongside X-Token every time.","Keep both secrets in one config object.","Add tests asserting both headers are present."],"tags":["fastapi","http-400","headers","authentication"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}