dgraph-io/dgraph · error
while refreshing JWK from the URL
Error message
while refreshing JWK from the URL
What it means
This error wraps any failure that occurs while re-fetching a JSON Web Key (JWK) set from one of the configured JWK URLs before JWT validation. The library refreshes the key set whenever the cached copy has expired (isExpired) and wraps the underlying fetch error (HTTP failure, bad URL, invalid JWK response) with this message. It is a wrapper, so the root cause is in the wrapped error.
Source
Thrown at graphql/authorization/auth.go:349
}
jwtToken := md.Get(string(AuthJwtCtxKey))
if len(jwtToken) != 1 {
return ""
}
return jwtToken[0]
}
// validateThroughJWKUrl validates the JWT token against the given list of JWKUrls.
// It returns an error only if the token is not validated against even one of the
// JWKUrl.
func (a *AuthMeta) validateThroughJWKUrl(jwtStr string) (*jwt.Token, error) {
var err error
var token *jwt.Token
for i := range a.JWKUrls {
if a.isExpired(i) {
err = a.refreshJWK(i)
if err != nil {
return nil, errors.Wrap(err, "while refreshing JWK from the URL")
}
}
token, err = jwt.ParseWithClaims(
jwtStr,
&CustomClaims{authMeta: a},
func(token *jwt.Token) (interface{}, error) {
kid := token.Header["kid"]
if kid == nil {
return nil, errors.Errorf("kid not present in JWT")
}
signingKeys := a.jwkSet[i].Key(kid.(string))
if len(signingKeys) == 0 {
return nil, errors.Errorf("Invalid kid")
}
return signingKeys[0].Key, nil
},View on GitHub (pinned to 759e242be6)
Solutions
- Inspect the wrapped cause (errors.Cause / %v) to see whether it is network, HTTP status, or JWK parsing — fix that root issue first.
- Verify the JWKUrls entries are reachable from this host (curl the URL from the server).
- Check the IdP status page / rate limits if the endpoint returns 429/5xx.
- If the cache is expiring too often, increase the expiry interval used by isExpired so refreshes are less frequent.
- Add retry with backoff around refreshJWK for transient network failures.
Example fix
// before
if a.isExpired(i) {
if err := a.refreshJWK(i); err != nil {
return nil, errors.Wrap(err, "while refreshing JWK from the URL")
}
}
// after
if a.isExpired(i) {
if err := retryWithBackoff(3, func() error { return a.refreshJWK(i) }); err != nil {
glog.Errorf("JWK refresh failed for %s: %v", a.JWKUrls[i], err)
return nil, errors.Wrapf(err, "while refreshing JWK from %s", a.JWKUrls[i])
}
} Defensive patterns
Strategy: retry
Validate before calling
// before validating tokens
for _, u := range auth.JWKUrls {
resp, err := http.Get(u)
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("JWK URL %s unreachable: %v", u, err)
}
resp.Body.Close()
} Try / catch
if claims, err := auth.ExtractCustomClaims(ctx, jwtStr); err != nil {
if strings.Contains(err.Error(), "while refreshing JWK from the URL") {
// fall back to cached keys or return 503
return nil, status.Error(codes.Unavailable, "auth key source unavailable")
}
return nil, err
} Prevention
- Monitor JWKS endpoint availability and alert on failures
- Add retry with backoff around JWK refreshes
- Keep a last-known-good JWK set to serve during refresh outages
- Set a sane JWK cache TTL so refreshes are infrequent
When it happens
Trigger: validateThroughJWKUrl iterates a.JWKUrls; for any index i where a.isExpired(i) is true, a.refreshJWK(i) fails — e.g. the JWKS endpoint returns 5xx, DNS/network failure, malformed JWK JSON, or a bad URL configured in JWKUrls.
Common situations: Identity provider (Auth0/Keycloak/Cognito) JWKS endpoint is down or rate-limiting; firewall blocks egress to the JWKS host; JWK URL typo; cached key set TTL elapsed right before an incoming request is validated; IdP rotated keys and the refresh endpoint changed.
Related errors
- kid not present in JWT
- expecting either JWKUrl or JWKUrls, both were given
- expecting either JWKUrl/JWKUrls or (VerificationKey, Algo),
- required field missing in Dgraph.Authorization:%s
- invalid Bearer-formatted header value for JWT (%s)
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/bff5e5d9480d689b.
Report an issue: GitHub.