crewAIInc/crewAI · error · HTTPException
Unable to fetch signing keys
Error message
Unable to fetch signing keys
What it means
Raised by OIDCAuth.authenticate() when the PyJWKClient cannot fetch or find signing keys (PyJWKClientError), e.g. the JWKS endpoint is unreachable, returns an error, or contains no key matching the token's kid. It maps to HTTP 503 Service Unavailable, signaling a transient upstream problem rather than an invalid credential, and logs the underlying error at ERROR level with reason='jwks_client_error'.
Source
Thrown at lib/crewai/src/crewai/a2a/auth/server_schemes.py:346
except jwt.MissingRequiredClaimError as e:
logger.debug(
"OIDC authentication failed",
extra={"reason": "missing_claim", "claim": e.claim, "scheme": "oidc"},
)
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail=f"Missing required claim: {e.claim}",
) from None
except jwt.PyJWKClientError as e:
logger.error(
"OIDC authentication failed",
extra={
"reason": "jwks_client_error",
"error": str(e),
"scheme": "oidc",
},
)
raise HTTPException(
status_code=HTTP_503_SERVICE_UNAVAILABLE,
detail="Unable to fetch signing keys",
) from None
except jwt.InvalidTokenError as e:
logger.debug(
"OIDC authentication failed",
extra={"reason": "invalid_token", "error": str(e), "scheme": "oidc"},
)
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail="Invalid or missing authentication credentials",
) from None
class OAuth2ServerAuth(ServerAuthScheme):
"""OAuth2 authentication for A2A server.
Declares OAuth2 security scheme in AgentCard and validates tokens usingView on GitHub (pinned to 754d7323be)
Solutions
- Verify the JWKS URL from the server host: curl -v <jwks_url> and fix DNS/firewall/TLS issues.
- Retry the request after a short delay — PyJWKClient caches keys, so a transient failure clears on the next fetch.
- Ensure jwks_url matches the IdP's current jwks_uri from its discovery document (rotated endpoints).
- For containerized deployments, confirm egress rules and CA trust so the JWKS fetch succeeds.
Defensive patterns
Strategy: retry
Validate before calling
import httpx
resp = httpx.get(jwks_url, timeout=5)
assert resp.status_code == 200 and resp.json().get("keys"), (
f"JWKS endpoint unhealthy: {resp.status_code}"
) Try / catch
for attempt in range(3):
try:
return await scheme.authenticate(token)
except HTTPException as e:
if e.status_code == 503 and e.detail == "Unable to fetch signing keys":
await asyncio.sleep(2 ** attempt) # transient upstream failure: back off and retry
else:
raise Prevention
- Health-check the JWKS endpoint as part of service readiness probes.
- Ensure container egress/DNS/CA trust allows reaching the IdP.
- Retry with backoff on 503 — JWKS failures are usually transient.
When it happens
Trigger: jwks_url points to a host that is down, times out, or returns non-200; the IdP rotated keys and the cached JWKS lacks the token's kid while refetch fails; a firewall/DNS failure between the CrewAI server and the IdP; JWKS endpoint behind rate limiting returning 429.
Common situations: IdP outage or maintenance window; network egress restrictions from containers (no DNS/egress to the IdP domain); key rotation races; self-signed TLS on the JWKS endpoint breaking the fetch.
Related errors
- Token introspection service unavailable
- Error. A valid pyproject.toml file is required. Check that a
- OIDC not initialized
- Token has expired
- Invalid token audience
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/2090db8bdab652cc.
Report an issue: GitHub.