Fosowl/agenticSeek · error · HTTPException

Missing or malformed Authorization header

Error message

Missing or malformed Authorization header

What it means

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.

Source

Thrown at sources/api_auth.py:21

Off by default: if AGENTICSEEK_API_TOKEN is unset, every request passes,
matching the existing local-only UX. Set AGENTICSEEK_API_TOKEN to require a
matching `Authorization: Bearer <token>` header on routes that depend on
require_api_token.
"""

import hmac
import os

from fastapi import Header, HTTPException


async def require_api_token(authorization: str | None = Header(default=None)) -> None:
    expected_token = os.getenv("AGENTICSEEK_API_TOKEN")
    if not expected_token:
        return

    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(
            status_code=401,
            detail="Missing or malformed Authorization header",
        )

    provided_token = authorization[len("Bearer "):]
    if not hmac.compare_digest(provided_token, expected_token):
        raise HTTPException(status_code=401, detail="Invalid API token")

View on GitHub (pinned to ae57a23577)

Solutions

  1. Send the header as `Authorization: Bearer <token>` matching the AGENTICSEEK_API_TOKEN value.
  2. Confirm the client/proxy isn't stripping the Authorization header (check logs or curl -v).
  3. If auth is not wanted, unset AGENTICSEEK_API_TOKEN in the server environment (dependency then returns early) — only for trusted/local setups.
  4. Use the exact capitalized "Bearer" scheme, as the check is a literal startswith comparison.

Example fix

// before
requests.get(f"{base}/api")
// after
requests.get(f"{base}/api", headers={"Authorization": f"Bearer {os.environ['AGENTICSEEK_API_TOKEN']}"})
Defensive patterns

Strategy: validation

Validate before calling

import os
def auth_headers():
    token = os.environ.get("AGENTICSEEK_API_TOKEN")
    if not token:
        return {}
    return {"Authorization": f"Bearer {token}"}
resp = requests.get(f"{base}/api", headers=auth_headers())

Type guard

def has_valid_auth_header(value: str | None) -> bool:
    return bool(value) and value.startswith("Bearer ") and len(value) > len("Bearer ")

Try / catch

try:
    resp = requests.get(url, headers=headers)
    resp.raise_for_status()
except requests.HTTPError as e:
    if e.response.status_code == 401 and "Missing or malformed" in e.response.json().get("detail", ""):
        headers["Authorization"] = f"Bearer {token}"  # add header and retry once
        resp = requests.get(url, headers=headers)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of Fosowl/agenticSeek@ae57a23577 (2026-08-30). Data as JSON: /api/errors/22ede83bbb028140. Report an issue: GitHub.