dgraph-io/dgraph · error
expecting either JWKUrl or JWKUrls, both were given
Error message
expecting either JWKUrl or JWKUrls, both were given
What it means
The `validate` method of Dgraph's Authorization configuration (AuthMeta, from the @auth directive's Dgraph.Authorization header) rejects configs that set both `JWKUrl` (single URL) and `JWKUrls` (list of URLs). Only one mechanism for supplying JSON Web Key sets is allowed.
Source
Thrown at graphql/authorization/auth.go:74
Namespace string
Algo string
SigningMethod jwt.SigningMethod `json:"-"` // Ignoring this field
Audience []string
httpClient *http.Client
ClosedByDefault bool
}
// Validate required fields.
func (a *AuthMeta) validate() error {
var fields string
// If JWKUrl/JWKUrls is provided, we don't expect (VerificationKey, Algo),
// they are needed only if JWKUrl/JWKUrls is not present there.
if len(a.JWKUrls) != 0 || a.JWKUrl != "" {
// User cannot provide both JWKUrl and JWKUrls.
if len(a.JWKUrls) != 0 && a.JWKUrl != "" {
return fmt.Errorf("expecting either JWKUrl or JWKUrls, both were given")
}
if a.VerificationKey != "" || a.Algo != "" {
return fmt.Errorf("expecting either JWKUrl/JWKUrls or (VerificationKey, Algo), both were given")
}
// Audience should be a required field if JWKUrl is provided.
if len(a.Audience) == 0 {
fields = " `Audience` "
}
} else {
if a.VerificationKey == "" {
fields = " `Verification key`/`JWKUrl`/`JWKUrls`"
}
if a.Algo == "" {
fields += " `Algo`"
}View on GitHub (pinned to 759e242be6)
Solutions
- Remove `JWKUrl` and keep only the `JWKUrls` array (preferred for multiple key sets)
- Or remove `JWKUrls` and keep only `JWKUrl` if you have exactly one JWKS endpoint
- Restart Dgraph after fixing the Dgraph.Authorization header value
Example fix
// before
Dgraph.Authorization: {"JWKUrl":"https://idp/.well-known/jwks.json","JWKUrls":["https://idp/.well-known/jwks.json"],"Namespace":"https://dgraph.io/jwt/claims","Audience":["dgraph"],"Algo":"RS256"}
// after
Dgraph.Authorization: {"JWKUrls":["https://idp/.well-known/jwks.json"],"Namespace":"https://dgraph.io/jwt/claims","Audience":["dgraph"],"Algo":"RS256"} Defensive patterns
Strategy: validation
Validate before calling
const auth = JSON.parse(process.env.DGRAPH_AUTHORIZATION);
if (auth.JWKUrl && Array.isArray(auth.JWKUrls) && auth.JWKUrls.length) {
throw new Error('Set either JWKUrl or JWKUrls, not both');
} Type guard
const usesSingleJwk = (a) => typeof a.JWKUrl === 'string' && a.JWKUrl !== '' && !(a.JWKUrls?.length); const usesMultipleJwks = (a) => Array.isArray(a.JWKUrls) && a.JWKUrls.length > 0 && !a.JWKUrl;
Prevention
- Pick one JWKS mechanism during config migrations and delete the other key
- Validate the Dgraph.Authorization JSON before deploying
- Keep a canonical auth config snippet in your repo
When it happens
Trigger: Setting the Dgraph.Authorization header so that its JSON contains a non-empty JWKUrls array AND a non-empty JWKUrl string at the same time, then calling Parse (typically at server start-up when the authorization header is parsed).
Common situations: Migrating a config from the old single JWKUrl field to the newer JWKUrls list and leaving the old key in place; copying a sample config that already had JWKUrl and adding JWKUrls without removing it; merging multiple auth config fragments.
Related errors
- expecting either JWKUrl/JWKUrls or (VerificationKey, Algo),
- required field missing in Dgraph.Authorization:%s
- audience value was expected but not provided
- jwt token cannot be validated because verification algorithm
- invalid jwt algorithm: found %s, but supported options are:
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/2b3b485bba456016.
Report an issue: GitHub.