{"record":{"id":"9be5cf0fe765a66e","repo":"SigNoz/signoz","slug":"errors-codeunauthenticated","errorCode":"errors.CodeUnauthenticated","errorMessage":"failed to parse jwt token","messagePattern":"failed to parse jwt token","errorType":"error_code","errorClass":null,"httpStatus":401,"severity":"error","filePath":"pkg/tokenizer/jwttokenizer/provider.go","lineNumber":210,"sourceCode":"\t\t}\n\t}\n\n\treturn stats, nil\n}\n\nfunc (provider *provider) getClaimsFromToken(token string) (Claims, error) {\n\tclaims := Claims{}\n\n\t_, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {\n\t\tif _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, errors.Newf(errors.TypeUnauthenticated, errors.CodeUnauthenticated, \"unrecognized signing algorithm: %s\", token.Method.Alg())\n\t\t}\n\n\t\treturn []byte(provider.config.JWT.Secret), nil\n\t})\n\n\tif err != nil {\n\t\treturn Claims{}, errors.Wrapf(err, errors.TypeUnauthenticated, errors.CodeUnauthenticated, \"failed to parse jwt token\")\n\t}\n\n\treturn claims, nil\n}\n\nfunc (provider *provider) Stop(ctx context.Context) error {\n\tclose(provider.stopC)\n\treturn nil\n}\n\nfunc (provider *provider) ListMaxLastObservedAtByOrgID(ctx context.Context, orgID valuer.UUID) (map[valuer.UUID]time.Time, error) {\n\tuserIDToLastObservedAts := provider.listLastObservedAtDesc(orgID)\n\n\tmaxLastObservedAtPerUserID := make(map[valuer.UUID]time.Time)\n\n\tfor _, userIDToLastObservedAt := range userIDToLastObservedAts {\n\t\tfor userID, lastObservedAt := range userIDToLastObservedAt {\n\t\t\tif lastObservedAt.IsZero() {","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/tokenizer/jwttokenizer/provider.go#L192-L228","documentation":"getClaimsFromToken parses a JWT using the provider's configured secret as the HMAC key and throws this unauthenticated error when parsing or signature verification fails. It is the common failure path behind GetIdentity, RotateToken, and SetLastObservedAt, so any token-validation problem surfaces here with the underlying jwt error wrapped.","triggerScenarios":"Calling GetIdentity/RotateToken/SetLastObservedAt with a malformed, tampered, or wrong-issuer/audience token, an expired token, or a token signed with a different secret than provider.config.JWT.Secret (e.g. token minted by another environment). Algorithm mismatches (token alg RS256 while the parser expects HS256 with a byte-secret) also land here.","commonSituations":"JWT_SECRET rotated or differing between services/environments, stale tokens held by clients after a secret change, clock skew causing expiry validation failures, or passing an opaque API key where a JWT is expected.","solutions":["Decode the wrapped jwt error: 'signature is invalid' points to a secret mismatch, 'token is expired' to expiry, 'token contains an invalid number of segments' to a malformed/non-JWT string","Ensure all services minting and validating tokens use the same JWT.Secret configuration value","If the secret was rotated, force clients to re-authenticate and obtain fresh tokens (old tokens will fail by design)","Verify the token is a well-formed JWT (three base64url segments) and not an opaque token or API key","Check server clocks (NTP) if expiry/nbf failures look spurious"],"exampleFix":"// before\nidentity, err := provider.GetIdentity(ctx, \"some-opaque-api-key\")\n\n// after\nidentity, err := provider.GetIdentity(ctx, jwtString) // must be a JWT signed with provider.config.JWT.Secret\nif errors.Ast(err, errors.TypeUnauthenticated) { /* re-auth / 401 */ }","handlingStrategy":"try-catch","validationCode":"// Cheap structural pre-check before calling identity APIs:\nfunc looksLikeJWT(s string) bool {\n    parts := strings.Split(s, \".\")\n    return len(parts) == 3\n}","typeGuard":"func isParsableJWT(s string) bool { return looksLikeJWT(s) }","tryCatchPattern":"claims, err := provider.GetIdentity(ctx, token)\nif err != nil {\n    if errors.Ast(err, errors.TypeUnauthenticated) {\n        // 401: distinguish via wrapped jwt error (signature vs expiry) for logging; client must re-auth\n    }\n    return err\n}","preventionTips":["Keep JWT.Secret identical across all minting and validating services; manage it via a single secret source","Return and use refresh flows so clients replace tokens before expiry instead of hitting parse failures","Never pass opaque tokens or API keys into JWT-backed identity APIs"],"tags":["jwt","authentication","signature-mismatch","expired-token","go"],"backgroundTag":"jwt-token-validation-failed","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}