harry0703/MoneyPrinterTurbo · error · HttpException
invalid token: {request_url}, {user_agent}
Error message
invalid token: {request_url}, {user_agent} What it means
Raised by verify_token in app/controllers/base.py when the x-api-key header does not match the api_key configured in config.app. Every authenticated v1 endpoint funnels through this check, so any mismatched or missing key yields a 401 before business logic runs. The message intentionally echoes the request URL and User-Agent to help server operators correlate rejected calls in logs.
Source
Thrown at app/controllers/base.py:27
def get_task_id(request: Request):
task_id = request.headers.get("x-task-id")
if not task_id:
task_id = uuid4()
return str(task_id)
def get_api_key(request: Request):
api_key = request.headers.get("x-api-key")
return api_key
def verify_token(request: Request):
token = get_api_key(request)
if token != config.app.get("api_key", ""):
request_id = get_task_id(request)
request_url = request.url
user_agent = request.headers.get("user-agent")
raise HttpException(
task_id=request_id,
status_code=401,
message=f"invalid token: {request_url}, {user_agent}",
)
View on GitHub (pinned to 1f9f19c202)
Solutions
- Compare the exact value of the x-api-key header against config.app['api_key'] in the running process; fix the client or the config so they match.
- If the server has no api_key configured, set one in the app config and restart, then use it on the client.
- Check that no proxy/gateway strips the x-api-key header and that the header name is lowercase-safe in your HTTP client.
- Verify the key is sent as a raw header value without extra quotes, 'Bearer ' prefix, or trailing newline.
Example fix
# before curl http://localhost:8080/api/v1/tasks -H "x-api-key: Bearer my-secret" # after curl http://localhost:8080/api/v1/tasks -H "x-api-key: my-secret"
Defensive patterns
Strategy: validation
Validate before calling
# client: fail fast on obviously missing/malformed key before any call
key = os.environ.get("APP_API_KEY", "")
if not key or key.strip() != key:
raise RuntimeError("APP_API_KEY is missing or has surrounding whitespace") Type guard
def is_valid_api_key_shape(key: str | None) -> bool:
return isinstance(key, str) and 0 < len(key) == len(key.strip()) Try / catch
# server-side callers: treat 401 as terminal, not retryable
try:
resp = client.get("/api/v1/tasks")
except HTTPError as e:
if e.response.status_code == 401:
raise RuntimeError("API key rejected; check x-api-key header vs server config") from e
raise Prevention
- Load the API key from one shared source (env/secret manager) for both client and server.
- Never send 'Bearer ' prefixes with x-api-key; the comparison is exact-string.
- Add a startup smoke test that calls one authenticated endpoint and fails deployment on 401.
When it happens
Trigger: Calling any /api/v1 endpoint without the x-api-key header; sending a key that differs from config.app['api_key']; rotating the key on the server while clients still use the old one; whitespace/quoting issues when the key is passed via curl or a shell variable.
Common situations: Fresh deployments where api_key was never set in the config file (defaults to empty string, so any non-empty sent key fails); CI pipelines that inject the key incorrectly; key rotated between environments (dev vs prod); proxy or gateway stripping custom headers.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ElevenLabs API key was rejected (401): {_safe_response_error
- ElevenLabs API key is required
- {llm_provider}: api_key is not set, please set it in the con
- Sonilo API key is required
- Sonilo connection failed ({response.status_code}): {_safe_re
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/427357a8b5330d8a.
Report an issue: GitHub.