{"record":{"id":"9baa33cdab0a1ddd","repo":"SigNoz/signoz","slug":"errcodetokenexpired","errorCode":"ErrCodeTokenExpired","errorMessage":"token has not been used for too long","messagePattern":"token has not been used for too long","errorType":"error_code","errorClass":"errors SigNozError","httpStatus":401,"severity":"error","filePath":"pkg/types/authtypes/token.go","lineNumber":141,"sourceCode":"\nfunc (typ *Token) IsValid(rotationInterval time.Duration, idleDuration time.Duration, maxDuration time.Duration) error {\n\t// Check for expiration\n\tif err := typ.IsExpired(idleDuration, maxDuration); err != nil {\n\t\treturn err\n\t}\n\n\t// Check for rotation\n\tif err := typ.IsRotationRequired(rotationInterval); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (typ *Token) IsExpired(idleDuration time.Duration, maxDuration time.Duration) error {\n\t// If now - last_seen_at > idle_duration, the token will be considered as expired.\n\tif !typ.LastObservedAt.IsZero() && typ.LastObservedAt.Before(time.Now().Add(-idleDuration)) {\n\t\treturn errors.New(errors.TypeUnauthenticated, ErrCodeTokenExpired, \"token has not been used for too long\")\n\t}\n\n\t// If now - created_at > max_duration, the token will be considered as expired.\n\tif typ.CreatedAt.Before(time.Now().Add(-maxDuration)) {\n\t\treturn errors.New(errors.TypeUnauthenticated, ErrCodeTokenExpired, \"token was created a long time ago\")\n\t}\n\n\treturn nil\n}\n\nfunc (typ *Token) IsRotationRequired(rotationInterval time.Duration) error {\n\tif !typ.RotatedAt.IsZero() && typ.RotatedAt.Before(time.Now().Add(-rotationInterval)) {\n\t\treturn errors.New(errors.TypeUnauthenticated, ErrCodeTokenRotationRequired, \"token needs to be rotated\")\n\t}\n\n\tif typ.RotatedAt.IsZero() && typ.CreatedAt.Before(time.Now().Add(-rotationInterval)) {\n\t\treturn errors.New(errors.TypeUnauthenticated, ErrCodeTokenRotationRequired, \"token needs to be rotated\")\n\t}","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/types/authtypes/token.go#L123-L159","documentation":"Returned by Token.IsExpired when LastObservedAt is older than the idle duration, i.e. the token hasn't been used recently. This implements idle expiry for API/refresh tokens.","triggerScenarios":"Calling IsValid or Rotate on a token whose lastObservedAt is before now minus idleDuration (e.g. unused for 30 days).","commonSituations":"Scripts/agents left unused over holidays, stale PATs, or environments where the token was never exercised after creation.","solutions":["Generate a new token by authenticating again","Use the token at least once per idle window to keep it alive","Ask the admin to configure a larger idleDuration if long-lived unattended tokens are intended"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if !tok.LastObservedAt.IsZero() && time.Since(tok.LastObservedAt) > idleDuration { /* re-authenticate */ }","typeGuard":null,"tryCatchPattern":"if err := tok.IsExpired(idle, max); err != nil {\n    if strings.Contains(err.Error(), \"not been used\") { /* idle expiry: re-login */ }\n}","preventionTips":["Exercise tokens on a schedule shorter than the idle window","Monitor LastObservedAt to predict idle expiry"],"tags":["tokens","auth","expiry","idle-timeout"],"backgroundTag":"token-expired","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}