{"record":{"id":"ebe2f73bbc97d358","repo":"ory/kratos","slug":"no-audience-matched-the-token-s-audience","errorCode":null,"errorMessage":"no audience matched the token's audience","messagePattern":"no audience matched the token's audience","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"selfservice/strategy/oidc/token_verifier.go","lineNumber":20,"sourceCode":"// SPDX-License-Identifier: Apache-2.0\n\npackage oidc\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\n\t\"github.com/ory/x/reqlog\"\n)\n\nfunc verifyToken(ctx context.Context, keySet oidc.KeySet, config *Configuration, rawIDToken, issuerURL string) (*Claims, error) {\n\ttokenAudiences := append([]string{config.ClientID}, config.AdditionalIDTokenAudiences...)\n\tvar token *oidc.IDToken\n\terr := fmt.Errorf(\"no audience matched the token's audience\")\n\tfor _, aud := range tokenAudiences {\n\t\tverifier := oidc.NewVerifier(issuerURL, keySet, &oidc.Config{\n\t\t\tClientID: aud,\n\t\t})\n\t\tt0 := time.Now()\n\t\ttoken, err = verifier.Verify(ctx, rawIDToken)\n\t\treqlog.AccumulateExternalLatency(ctx, time.Since(t0))\n\t\tif err != nil && strings.Contains(err.Error(), \"oidc: expected audience\") {\n\t\t\t// The audience is not the one we expect, try the next one\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\t// Something else went wrong\n\t\t\treturn nil, err\n\t\t}\n\t\t// The token was verified successfully\n\t\tbreak\n\t}\n\tif err != nil {","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/selfservice/strategy/oidc/token_verifier.go#L2-L38","documentation":"verifyToken tries to verify the OIDC ID token against each configured audience (ClientID plus AdditionalIDTokenAudiences) using an oidc.Verifier per audience. It initializes err to this sentinel and, if no verifier succeeds, this is the error that surfaces (often wrapped by error [36]). It means the token's 'aud' claim did not include any audience configured for this OIDC client.","triggerScenarios":"An ID token presented to the OIDC self-service strategy has an aud claim that matches neither config.ClientID nor any entry in config.AdditionalIDTokenAudiences — e.g. token issued for a different client_id, or the provider puts the client in 'azp' only while aud lists other values.","commonSituations":"Misconfigured Ory Kratos OIDC client_id not matching the provider app's client ID; provider (e.g. Auth0, Keycloak) issuing tokens with an audience for a different API/audience; missing additional audiences after adding a second provider client; clock or issuer mismatches surfacing through the same verify loop.","solutions":["Check the token's 'aud' claim (decode the JWT) and set config.ClientID (oidc client_id in Kratos config) to match one of its values exactly.","If the token legitimately targets multiple audiences, add the correct value to selfservice.methods.oidc.config.additional_id_token_audiences (AdditionalIDTokenAudiences).","Confirm you are validating the ID token from the same provider/client that issued it — not a token minted for another application or API resource.","If your provider relies on 'azp' instead of 'aud', configure the provider or use a token that carries your client_id in aud."],"exampleFix":"// before (kratos.yml)\nselfservice:\n  methods:\n    oidc:\n      config:\n        client_id: wrong-client\n// after\nselfservice:\n  methods:\n    oidc:\n      config:\n        client_id: my-actual-provider-client-id\n        additional_id_token_audiences: [\"other-accepted-audience\"]","handlingStrategy":"validation","validationCode":"function checkAudience(idToken, allowed) {\n  const payload = JSON.parse(atob(idToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')))\n  const auds = Array.isArray(payload.aud) ? payload.aud : [payload.aud]\n  if (!auds.some(a => allowed.includes(a))) {\n    throw new Error(`token aud ${auds.join(',')} not in ${allowed.join(',')}`)\n  }\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"no audience matched\") {\n    // decode token, compare aud claim to configured client_id / additional audiences\n}","preventionTips":["Keep Kratos OIDC client_id in sync with the provider app's client ID","Add every legitimate audience to additional_id_token_audiences","Decode tokens during debugging to inspect aud/azp claims"],"tags":["oidc","jwt","audience","authentication"],"backgroundTag":"jwt-audience-mismatch","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}