cloudflare/cloudflared · error
metadata JWT verification failed (%v) and JWKS refresh also
Error message
metadata JWT verification failed (%v) and JWKS refresh also failed: %w
What it means
Compound failure in verifyMetadataWithRetry: the access JWT failed verification against the cached JWKS, and the one allowed refresh path also failed because fetchJWKS returned an error (the retry exists to handle key rotation). The token cannot be verified at all, so GetAppInfo and the token flow abort.
Source
Thrown at token/jwks.go:244
// verification retries once only when the cached keys are old enough to refresh.
func verifyMetadataWithRetry(rawJWT string, authDomain url.URL) (*metadataClaims, error) {
keySet, cachedAt, err := getJWKSWithCache(authDomain)
if err != nil {
return nil, err
}
claims, err := verifyMetadataJWT(rawJWT, keySet)
if err == nil {
return claims, nil
}
if cachedAt.IsZero() || time.Since(cachedAt) < jwksMinRefreshInterval {
return nil, err
}
// Verification failed; this could be key rotation. Re-fetch JWKS and retry.
keySet, fetchErr := fetchJWKS(authDomain)
if fetchErr != nil {
return nil, fmt.Errorf("metadata JWT verification failed (%v) and JWKS refresh also failed: %w", err, fetchErr)
}
if err := writeJWKSCache(authDomain, keySet); err != nil {
log.Debug().Err(err).Msg("failed to write refreshed JWKS cache; continuing with fetched keys")
}
return verifyMetadataJWT(rawJWT, keySet)
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Check network reachability of the JWKS endpoint — the underlying fetchErr says why the refresh failed.
- If the JWT is expired or signed by unknown keys, obtain a new access token.
- Retry after the jwksMinRefreshInterval window elapses.
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at token/jwks.go:244 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/8fccb63c0b6b3914.
Report an issue: GitHub.