{"record":{"id":"544446ac25cc29fd","repo":"cloudflare/cloudflared","slug":"token-has-non-cloudflare-issuer-of-s-s","errorCode":null,"errorMessage":"token has non-cloudflare issuer of %s: %s","messagePattern":"token has non-cloudflare issuer of (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"validation/validation.go","lineNumber":208,"sourceCode":"\tkeySet := oidc.NewRemoteKeySet(ctx, domainURL+accessCertPath)\n\treturn &Access{oidc.NewVerifier(issuerURL, keySet, &oidc.Config{ClientID: applicationAUD})}, nil\n}\n\nfunc (a *Access) Validate(ctx context.Context, jwt string) error {\n\ttoken, err := a.verifier.Verify(ctx, jwt)\n\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"token is invalid: %s\", jwt)\n\t}\n\n\t// Perform extra sanity checks, just to be safe.\n\n\tif token == nil {\n\t\treturn fmt.Errorf(\"token is nil: %s\", jwt)\n\t}\n\n\tif !strings.HasSuffix(token.Issuer, accessDomain) {\n\t\treturn fmt.Errorf(\"token has non-cloudflare issuer of %s: %s\", token.Issuer, jwt)\n\t}\n\n\treturn nil\n}\n\nfunc (a *Access) ValidateRequest(ctx context.Context, r *http.Request) error {\n\treturn a.Validate(ctx, r.Header.Get(accessJwtHeader))\n}\n","sourceCodeStart":190,"sourceCodeEnd":217,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/validation/validation.go#L190-L217","documentation":"After verifying the JWT's signature, Validate checks that the token's issuer ends with 'cloudflareaccess.com'. A validly-signed token issued by something other than Cloudflare Access is rejected — usually a misconfiguration where the application AUD/issuer domain doesn't match the token's actual Access team.","triggerScenarios":"ValidateRequest receiving a Cf-Access-Jwt-Assertion JWT whose 'iss' claim is not a *.cloudflareaccess.com URL — e.g. token minted by a different Access team domain, another OIDC provider's token forwarded by a proxy, or a stale issuer configured in NewAccessValidator.","commonSituations":"Multiple Access applications/teams where the wrong team's token reaches this app; self-hosted or third-party OIDC tokens in the header; after migrating teams the validator still points at the old issuer; load balancers forwarding foreign JWTs.","solutions":["Confirm the JWT's iss claim (decode the token payload) and configure NewAccessValidator with that team's exact domain/issuer","Ensure the request actually came through the Cloudflare Access deployment for this team, not another team or a direct origin hit","Check the application AUD passed to NewAccessValidator matches this Access application","Reject or log the offending token source — something is injecting non-Access JWTs into the header"],"exampleFix":"// before\nvalidator, err := validation.NewAccessValidator(ctx, \"old-team.cloudflareaccess.com\", \"https://old-team.cloudflareaccess.com\", aud)\n// after — match the team that actually issues the tokens\nvalidator, err := validation.NewAccessValidator(ctx, \"myteam.cloudflareaccess.com\", \"https://myteam.cloudflareaccess.com\", aud)","handlingStrategy":"validation","validationCode":"func issuerIsCloudflare(jwt string) bool {\n    parts := strings.Split(jwt, \".\")\n    if len(parts) != 3 { return false }\n    var claims struct{ Iss string `json:\"iss\"` }\n    raw, _ := base64.RawURLEncoding.DecodeString(parts[1])\n    _ = json.Unmarshal(raw, &claims)\n    return strings.HasSuffix(claims.Iss, \"cloudflareaccess.com\")\n}","typeGuard":null,"tryCatchPattern":"if err := validator.Validate(ctx, jwt); err != nil {\n    if strings.Contains(err.Error(), \"non-cloudflare issuer\") {\n        log.Warn().Msg(\"token from wrong Access team or foreign OIDC provider\")\n    }\n    http.Error(w, \"Unauthorized\", http.StatusUnauthorized)\n}","preventionTips":["Match NewAccessValidator's domain/issuer/AUD to the exact Access team issuing tokens","Decode and log the iss claim when diagnosing auth failures","Ensure only the Cloudflare Access proxy can reach the origin (no direct ingress)"],"tags":["jwt","oidc","access","issuer","security"],"backgroundTag":"jwt-issuer-mismatch","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}