SigNoz/signoz · error
errors.CodeUnauthenticated
errors.CodeUnauthenticated
Error message
failed to parse jwt token
What it means
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.
Source
Thrown at pkg/tokenizer/jwttokenizer/provider.go:210
}
}
return stats, nil
}
func (provider *provider) getClaimsFromToken(token string) (Claims, error) {
claims := Claims{}
_, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.Newf(errors.TypeUnauthenticated, errors.CodeUnauthenticated, "unrecognized signing algorithm: %s", token.Method.Alg())
}
return []byte(provider.config.JWT.Secret), nil
})
if err != nil {
return Claims{}, errors.Wrapf(err, errors.TypeUnauthenticated, errors.CodeUnauthenticated, "failed to parse jwt token")
}
return claims, nil
}
func (provider *provider) Stop(ctx context.Context) error {
close(provider.stopC)
return nil
}
func (provider *provider) ListMaxLastObservedAtByOrgID(ctx context.Context, orgID valuer.UUID) (map[valuer.UUID]time.Time, error) {
userIDToLastObservedAts := provider.listLastObservedAtDesc(orgID)
maxLastObservedAtPerUserID := make(map[valuer.UUID]time.Time)
for _, userIDToLastObservedAt := range userIDToLastObservedAts {
for userID, lastObservedAt := range userIDToLastObservedAt {
if lastObservedAt.IsZero() {View on GitHub (pinned to 5069bf80b0)
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
Example fix
// before
identity, err := provider.GetIdentity(ctx, "some-opaque-api-key")
// after
identity, err := provider.GetIdentity(ctx, jwtString) // must be a JWT signed with provider.config.JWT.Secret
if errors.Ast(err, errors.TypeUnauthenticated) { /* re-auth / 401 */ } Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap structural pre-check before calling identity APIs:
func looksLikeJWT(s string) bool {
parts := strings.Split(s, ".")
return len(parts) == 3
} Type guard
func isParsableJWT(s string) bool { return looksLikeJWT(s) } Try / catch
claims, err := provider.GetIdentity(ctx, token)
if err != nil {
if errors.Ast(err, errors.TypeUnauthenticated) {
// 401: distinguish via wrapped jwt error (signature vs expiry) for logging; client must re-auth
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- CodeInvalidInput
- ErrCodeIncorrectPassword
- api_key_expired
- errors.CodeUnauthenticated
- CodeTooManyRequests
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/9be5cf0fe765a66e.
Report an issue: GitHub.