{"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/42a41db11f6882807ac3c057b942178d53b97438/docs_src/dependencies/tutorial012_py310.py#L1-L26","documentation":"Non-Annotated variant of error 29: `verify_key` (`x_key: str = Header()`) raises HTTP 400 \"X-Key header invalid\" when X-Key differs from \"fake-super-secret-key\". Runs as the second global dependency after verify_token.","triggerScenarios":"Any request that passes verify_token but sends a missing/wrong X-Key header.","commonSituations":"Second key forgotten; key-pair mismatch; header stripping by proxies.","solutions":["Send `X-Key: fake-super-secret-key` alongside a valid X-Token.","Store both keys in configuration.","Return 401 for key failures.","Centralize header injection in the client SDK."],"exampleFix":"# before\nif x_key != \"fake-super-secret-key\":\n    raise HTTPException(status_code=400, detail=\"X-Key header invalid\")\n\n# after\nif x_key != settings.expected_key:\n    raise HTTPException(status_code=401, detail=\"Unauthorized\")","handlingStrategy":"validation","validationCode":"if headers.get(\"X-Key\") != EXPECTED_KEY:\n    raise PermissionError(\"missing/invalid X-Key\")","typeGuard":"def key_ok(headers: dict) -> bool:\n    return headers.get(\"X-Key\") == EXPECTED_KEY","tryCatchPattern":"r = client.get(\"/users/\", headers=headers)\nif r.status_code == 400 and \"X-Key header invalid\" in r.json().get(\"detail\", \"\"):\n    ...","preventionTips":["Attach both keys via a single auth helper.","Rotate keys together and update all clients atomically.","Validate both headers before the request."],"tags":["fastapi","authentication","headers","global-dependency","http-400"],"analyzedSha":"42a41db11f6882807ac3c057b942178d53b97438","analyzedAt":"2026-08-04T19:23:32.007Z","schemaVersion":2}