Fosowl/agenticSeek · error · HTTPException

Invalid API token

Error message

Invalid API token

What it means

After validating the header format, require_api_token compares the provided Bearer token to AGENTICSEEK_API_TOKEN using hmac.compare_digest (constant-time). Any mismatch returns 401 with "Invalid API token". This means the header was well-formed but the credential value is wrong.

Source

Thrown at sources/api_auth.py:28

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. Regenerate/verify the token and set the exact same AGENTICSEEK_API_TOKEN value on the client.
  2. Strip whitespace/newlines/quotes from the token value before sending (token.strip()).
  3. Diff the server's env (`printenv AGENTICSEEK_API_TOKEN`) against what the client sends to confirm they match byte-for-byte.
  4. If loading from a secret file, read with .read().strip() to avoid trailing newline mismatches.

Example fix

// before
token = open("token.txt").read()  # may contain trailing \n
headers = {"Authorization": f"Bearer {token}"}  # 401 Invalid API token
// after
token = open("token.txt").read().strip()
headers = {"Authorization": f"Bearer {token}"}
Defensive patterns

Strategy: validation

Validate before calling

import os
def get_bearer_header(env_var="AGENTICSEEK_API_TOKEN") -> dict:
    token = os.environ.get(env_var, "").strip().strip('"')
    if not token:
        raise RuntimeError(f"{env_var} not set on client")
    return {"Authorization": f"Bearer {token}"}

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 "Invalid API token" in e.response.json().get("detail", ""):
        token = input("Token rejected; re-enter AGENTICSEEK_API_TOKEN value: ").strip()
        headers["Authorization"] = f"Bearer {token}"
        resp = requests.get(url, headers=headers)
    else:
        raise

Prevention

When it happens

Trigger: Sending Authorization: Bearer <token> where token != os.getenv("AGENTICSEEK_API_TOKEN") — wrong/stale token, whitespace or quoting around the value, trailing newline from a file-based secret, or client pointing at an environment with a different token.

Common situations: Client and server configured from different .env files; token rotated on the server but not the client; copying the token with surrounding quotes or a trailing \n; extra spaces after "Bearer "; staging vs. production tokens mixed up.

Related errors


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