Zie619/n8n-workflows · error · HTTPException
Invalid authentication token
Error message
Invalid authentication token
What it means
Raised by the admin reindex endpoint in api_server.py when the supplied admin_token does not equal the ADMIN_TOKEN environment variable. It is a deliberate 401 authentication rejection protecting a destructive/background indexing operation. The server also logs 'Security: Unauthorized reindex attempt from {client_ip}' whenever it fires.
Source
Thrown at api_server.py:603
status_code=429, detail="Rate limit exceeded. Please try again later."
)
# Security: Basic authentication check
# In production, use proper authentication (JWT, OAuth, etc.)
# For now, check for environment variable or disable endpoint
expected_token = os.environ.get("ADMIN_TOKEN", None)
if not expected_token:
# If no token is configured, disable the endpoint for security
raise HTTPException(
status_code=503,
detail="Reindexing endpoint is disabled. Set ADMIN_TOKEN environment variable to enable.",
)
if admin_token != expected_token:
print(f"Security: Unauthorized reindex attempt from {client_ip}")
raise HTTPException(status_code=401, detail="Invalid authentication token")
def run_indexing():
try:
db.index_all_workflows(force_reindex=force)
print(f"Reindexing completed successfully (requested by {client_ip})")
except Exception as e:
print(f"Error during reindexing: {e}")
background_tasks.add_task(run_indexing)
return {"message": "Reindexing started in background", "requested_by": client_ip}
@app.get("/api/integrations")
async def get_integrations():
"""Get list of all unique integrations."""
try:
stats = db.get_stats()
# For now, return basic info. Could be enhanced to return detailed integration statsView on GitHub (pinned to 94007c1445)
Solutions
- Confirm the exact value of ADMIN_TOKEN in the server process environment (print len() or a hash, never the value) and re-send a token that matches it exactly.
- Check how the endpoint declares the admin_token parameter (query vs header vs body) and send it in that position.
- Strip whitespace when setting the env var: export ADMIN_TOKEN=$(cat token.txt | tr -d '[:space:]') or fix the .env line.
- If ADMIN_TOKEN is unset you will instead get a 503 'endpoint is disabled' — set the variable to enable the endpoint, then authenticate.
Example fix
# before
resp = requests.post("http://host/api/reindex", params={"force": True}) # 401: no token
# after
import os
resp = requests.post(
"http://host/api/reindex",
params={"force": True, "admin_token": os.environ["ADMIN_TOKEN"]},
) Defensive patterns
Strategy: validation
Validate before calling
import os
def can_reindex() -> tuple[bool, str]:
token = os.environ.get("ADMIN_TOKEN")
if not token:
return False, "ADMIN_TOKEN not set on client; endpoint will return 503/401"
return True, token
# before the call:
ok, token = can_reindex()
if ok:
requests.post(f"{BASE}/api/reindex", params={"admin_token": token, "force": False}) Try / catch
try:
resp = requests.post(url, params={"admin_token": token}, timeout=30)
resp.raise_for_status()
except requests.HTTPError as e:
status = e.response.status_code
if status == 401:
# credential mismatch: re-read ADMIN_TOKEN from source of truth, never retry in a loop
raise RuntimeError("Admin token rejected; refresh credential") from e
if status == 503:
raise RuntimeError("Endpoint disabled; ADMIN_TOKEN unset on server") from e
raise Prevention
- Load the admin token from a secrets manager or env file at call time instead of hardcoding a copy that drifts.
- Never retry a 401 automatically — treat it as a credential bug, not a transient failure.
- Alert on the server log line 'Security: Unauthorized reindex attempt' to catch misconfigured clients early.
When it happens
Trigger: POST to the reindex endpoint (e.g. /api/reindex?force=true) with a missing, misspelled, or stale admin_token argument while ADMIN_TOKEN is set in the server environment. Also triggered when the client sends a token computed against a different ADMIN_TOKEN value than the one the server process was started with.
Common situations: ADMIN_TOKEN was rotated or differs between environments (dev vs prod); the server was restarted with a new env var but the client still uses the old token; the token is passed as a header while the endpoint expects it as a query/body parameter (or vice versa); trailing whitespace/newline in the env var from a .env file.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid filename format
- Rate limit exceeded. Please try again later.
- Access denied
- Reindexing endpoint is disabled. Set ADMIN_TOKEN environment
- str(e)
AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15).
Data as JSON: /api/errors/980ca83bbbc420a5.
Report an issue: GitHub.