{"record":{"id":"2030fb8766448690","repo":"dgraph-io/dgraph","slug":"audience-value-was-expected-but-not-provided","errorCode":null,"errorMessage":"audience value was expected but not provided","messagePattern":"audience value was expected but not provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphql/authorization/auth.go","lineNumber":290,"sourceCode":"\t// and other claims present in the token.\n\tfor k, v := range c.AuthVariables {\n\t\tresult[k] = v\n\t}\n\n\t// update `AuthVariables` with `result` map\n\tc.AuthVariables = result\n\treturn nil\n}\n\nfunc (c *CustomClaims) validateAudience() error {\n\t// If there's no audience claim, ignore\n\tif len(c.Audience) == 0 {\n\t\treturn nil\n\t}\n\n\t// If there is an audience claim, but no value provided, fail\n\tif c.authMeta.Audience == nil {\n\t\treturn fmt.Errorf(\"audience value was expected but not provided\")\n\t}\n\n\tvar match = false\n\tfor _, audStr := range c.Audience {\n\t\tfor _, expectedAudStr := range c.authMeta.Audience {\n\t\t\tif subtle.ConstantTimeCompare([]byte(audStr), []byte(expectedAudStr)) == 1 {\n\t\t\t\tmatch = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif !match {\n\t\treturn fmt.Errorf(\"JWT `aud` value doesn't match with the audience\")\n\t}\n\treturn nil\n}\n\nfunc (a *AuthMeta) ExtractCustomClaims(ctx context.Context) (*CustomClaims, error) {","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/graphql/authorization/auth.go#L272-L308","documentation":"`validateAudience` verifies the JWT's `aud` claim against the Audience list configured in Dgraph.Authorization. If the token contains an `aud` claim but the server configuration has no Audience values (authMeta.Audience is nil), validation cannot succeed and this error is returned.","triggerScenarios":"A request whose JWT includes an audience claim while the Dgraph.Authorization header was parsed with an empty/absent Audience array — e.g. the IDP always sets `aud` but the Dgraph config omitted `\"Audience\":[\"...\"]`.","commonSituations":"Deploying Dgraph against an IDP that mandatorily issues `aud` while the config was written for a token without one; Audience accidentally left as an empty array; switching IDPs whose tokens always carry aud.","solutions":["Add the expected audience value(s) to the `Audience` array in the Dgraph.Authorization header so it matches the token's `aud` claim","Check the token's `aud` (e.g. jwt.io) and copy that exact string into the config","Restart Dgraph after updating the authorization header"],"exampleFix":"// before\nDgraph.Authorization: {\"JWKUrl\":\"https://idp/jwks.json\",\"Namespace\":\"https://dgraph.io/jwt/claims\",\"Algo\":\"RS256\"}\n// after\nDgraph.Authorization: {\"JWKUrl\":\"https://idp/jwks.json\",\"Namespace\":\"https://dgraph.io/jwt/claims\",\"Audience\":[\"my-api-audience\"],\"Algo\":\"RS256\"}","handlingStrategy":"validation","validationCode":"const payload = JSON.parse(atob(jwt.split('.')[1]));\nif (payload.aud && !(config.Audience?.length)) {\n  throw new Error('Token has aud claim but Dgraph.Authorization Audience is empty');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Decode an actual IDP token and mirror its aud into the config","Always configure Audience when the IDP mandates aud claims"],"tags":["jwt","audience","authentication","configuration"],"backgroundTag":"jwt-audience-mismatch","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}