langflow-ai/langflow · error · HTTPException
Invalid API key
Error message
Invalid API key
What it means
Raised by _enforce_a2a_auth when the x-api-key is presented but either fails check_key (unknown/disabled key) or belongs to a different user than the flow owner. The same message covers both cases intentionally: revealing 'valid key, wrong user' would disclose that the key works elsewhere. The key must be issued by the flow's owner account.
Source
Thrown at src/backend/base/langflow/api/v1/a2a.py:136
# Short writable session (check_key flushes usage counters), closed before
# dispatch so no lock is held across the up-to-300s run.
async with session_scope() as session:
auth_type = await folder_auth_type(flow, session)
if auth_type == "none":
return # public agent
if auth_type not in ("apikey", "oauth"):
# Protected folder with a scheme A2A can't enforce: fail closed, never public.
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"A2A access is disabled for this agent: unsupported folder auth type {auth_type!r}.",
)
api_key = request.headers.get(A2A_APIKEY_HEADER)
if not api_key:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="API key required")
user = await check_key(session, api_key)
# Same message for invalid and wrong-owner: don't reveal a key is valid for another user.
if user is None or user.id != flow.user_id:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid API key")
class _FlowContextBuilder(DefaultServerCallContextBuilder):
"""Carry the per-request flow_id into the shared executor via call-context state."""
def build(self, request: Request) -> ServerCallContext:
context = super().build(request)
# Canonicalize to the same string form the resume guard uses (str(UUID(...))), so the durable
# store scope (_task_scope / _push_config_scope) and the checkpoint/resume guard agree even for
# a non-canonical UUID in the path (uppercase or hyphenless, both valid to the UUID route
# converter). Without this, the same task addressed via two encodings lands in two scopes.
context.state["flow_id"] = str(UUID(request.path_params["flow_id"]))
return context
async def _is_public_a2a_flow(flow: Flow) -> bool:
"""Whether an A2A flow admits callers without an API key."""
async with session_scope_readonly() as session:View on GitHub (pinned to 976ec789d2)
Solutions
- Regenerate an API key under the flow owner's account and use that in x-api-key
- Verify the key still exists and is active in the owner's API-keys page (it may have been revoked)
- Confirm flow ownership — if the flow belongs to user A, only user A's keys work; transfer the flow or use the owner's key
Example fix
# before
headers={"x-api-key": os.environ["ADMIN_API_KEY"]}
# after
headers={"x-api-key": os.environ["FLOW_OWNER_API_KEY"]} Defensive patterns
Strategy: validation
Validate before calling
import httpx
def key_is_live(base_url: str, api_key: str, auth: str) -> bool:
r = httpx.get(f"{base_url}/api/v1/api_keys/", headers={"x-api-key": api_key}, auth=auth)
return r.status_code == 200 # a valid, active key lists fine Try / catch
try:
resp = await client.send_message(flow_id, payload)
except A2AClientError as e:
if "Invalid API key" in str(e):
key = rotate_to_owner_key(flow_id) # fetch/regenerate under the flow owner
client = rebuild_client_with_x_api_key(key)
resp = await client.send_message(flow_id, payload)
else:
raise Prevention
- Issue the A2A key from the same account that owns the agent flow
- Store the flow_id and its owner-key together in secrets management as one unit
- On 401, treat 'Invalid API key' as either revoked or wrong-owner — check both before retrying
When it happens
Trigger: POST /api/v1/a2a/{flow_id}/jsonrpc with an x-api-key that is revoked, mistyped, from another user's account, or a key created after the server cached key state.
Common situations: Using an admin/personal key from a different account than the one that owns the agent flow; copying a key from another environment; a key revoked or rotated after the client was configured.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- API key required
- A2A access is disabled for this agent: unsupported folder au
- Incorrect username or password
- Invalid refresh token
- This project is configured for OAuth authentication, but the
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/c83543be03f3d8e4.
Report an issue: GitHub.