{"record":{"id":"22ede83bbb028140","repo":"Fosowl/agenticSeek","slug":"missing-or-malformed-authorization-header","errorCode":null,"errorMessage":"Missing or malformed Authorization header","messagePattern":"Missing or malformed Authorization header","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"sources/api_auth.py","lineNumber":21,"sourceCode":"Off by default: if AGENTICSEEK_API_TOKEN is unset, every request passes,\nmatching the existing local-only UX. Set AGENTICSEEK_API_TOKEN to require a\nmatching `Authorization: Bearer <token>` header on routes that depend on\nrequire_api_token.\n\"\"\"\n\nimport hmac\nimport os\n\nfrom fastapi import Header, HTTPException\n\n\nasync def require_api_token(authorization: str | None = Header(default=None)) -> None:\n    expected_token = os.getenv(\"AGENTICSEEK_API_TOKEN\")\n    if not expected_token:\n        return\n\n    if not authorization or not authorization.startswith(\"Bearer \"):\n        raise HTTPException(\n            status_code=401,\n            detail=\"Missing or malformed Authorization header\",\n        )\n\n    provided_token = authorization[len(\"Bearer \"):]\n    if not hmac.compare_digest(provided_token, expected_token):\n        raise HTTPException(status_code=401, detail=\"Invalid API token\")\n","sourceCodeStart":3,"sourceCodeEnd":29,"githubUrl":"https://github.com/Fosowl/agenticSeek/blob/ae57a2357745a9706cb12d0fd76d954c84d166fa/sources/api_auth.py#L3-L29","documentation":"The FastAPI dependency require_api_token enforces Bearer authentication when AGENTICSEEK_API_TOKEN is set. If the Authorization header is absent or does not start with \"Bearer \", it returns 401 with this detail. This check runs before the token value comparison; if no env token is configured the endpoint is intentionally open.","triggerScenarios":"Hitting a protected endpoint with no Authorization header, or a header like \"Token abc\", \"bearer abc\" (lowercase scheme, if startswith is case-sensitive), or just the raw token without the \"Bearer \" prefix — while AGENTICSEEK_API_TOKEN is set in the server environment.","commonSituations":"Client forgot to send the header at all; sending only the token value without the Bearer scheme; proxy/gateway stripping the Authorization header; using a non-Bearer auth scheme; server has the env var set but the client was written when auth was disabled.","solutions":["Send the header as `Authorization: Bearer <token>` matching the AGENTICSEEK_API_TOKEN value.","Confirm the client/proxy isn't stripping the Authorization header (check logs or curl -v).","If auth is not wanted, unset AGENTICSEEK_API_TOKEN in the server environment (dependency then returns early) — only for trusted/local setups.","Use the exact capitalized \"Bearer\" scheme, as the check is a literal startswith comparison."],"exampleFix":"// before\nrequests.get(f\"{base}/api\")\n// after\nrequests.get(f\"{base}/api\", headers={\"Authorization\": f\"Bearer {os.environ['AGENTICSEEK_API_TOKEN']}\"})","handlingStrategy":"validation","validationCode":"import os\ndef auth_headers():\n    token = os.environ.get(\"AGENTICSEEK_API_TOKEN\")\n    if not token:\n        return {}\n    return {\"Authorization\": f\"Bearer {token}\"}\nresp = requests.get(f\"{base}/api\", headers=auth_headers())","typeGuard":"def has_valid_auth_header(value: str | None) -> bool:\n    return bool(value) and value.startswith(\"Bearer \") and len(value) > len(\"Bearer \")","tryCatchPattern":"try:\n    resp = requests.get(url, headers=headers)\n    resp.raise_for_status()\nexcept requests.HTTPError as e:\n    if e.response.status_code == 401 and \"Missing or malformed\" in e.response.json().get(\"detail\", \"\"):\n        headers[\"Authorization\"] = f\"Bearer {token}\"  # add header and retry once\n        resp = requests.get(url, headers=headers)\n    else:\n        raise","preventionTips":["Always send the header as `Authorization: Bearer <token>` (capital B, single space).","Confirm your reverse proxy does not strip the Authorization header.","Keep client and server auth config in sync — read the same env var both sides.","In tests, hit the endpoint once at startup to verify auth wiring before real traffic."],"tags":["http","auth","fastapi","security"],"backgroundTag":"missing-authorization-header","analyzedSha":"ae57a2357745a9706cb12d0fd76d954c84d166fa","analyzedAt":"2026-08-30T02:49:05.834Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}