AlistGo/alist · warning
token not active yet
Error message
token not active yet
What it means
ParseToken maps jwt.ValidationErrorNotValidYet to this message: the token's nbf (NotBefore) claim is in the future, so the token is not yet acceptable. Tokens minted by GenerateToken set nbf = now, so this normally indicates clock skew or a manipulated token.
Source
Thrown at server/common/auth.go:55
validTokenCache.Set(tokenString, true)
return tokenString, err
}
func ParseToken(tokenString string) (*UserClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
return SecretKey, nil
})
if IsTokenInvalidated(tokenString) {
return nil, errors.New("token is invalidated")
}
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, errors.New("that's not even a token")
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
return nil, errors.New("token is expired")
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
return nil, errors.New("token not active yet")
} else {
return nil, errors.New("couldn't handle this token")
}
}
}
if claims, ok := token.Claims.(*UserClaims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("couldn't handle this token")
}
func InvalidateToken(tokenString string) error {
if tokenString == "" {
return nil // don't invalidate empty guest token
}
validTokenCache.Del(tokenString)
return nil
}View on GitHub (pinned to 843d9dc814)
Solutions
- Sync clocks (NTP/chrony) on all servers that issue or verify tokens
- If skew is unavoidable, add validation leeway when calling jwt.ParseWithClaims so small nbf differences are tolerated
- Regenerate the token after clocks are corrected
Example fix
// before
token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, kf) // no leeway
// after
token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, kf,
jwt.WithLeeway(30*time.Second)) Defensive patterns
Strategy: validation
Validate before calling
if time.Until(time.Unix(claims.NotBefore.Unix(), 0)) > 2*time.Minute {
// clock skew or forged nbf; reject before JWT parse
} Try / catch
_, err := common.ParseToken(tok)
if err != nil && strings.Contains(err.Error(), "not active yet") {
// check NTP sync, then ask client to retry shortly
} Prevention
- Run NTP on all token-issuing and token-verifying hosts
- Add leeway to JWT parsing when small skew is expected
When it happens
Trigger: Verifying a token on a server whose clock is behind the issuing server by more than the leeway, or using a hand-crafted token with a future nbf.
Common situations: NTP drift between nodes in multi-instance deployments; container host clock wrong; token generated on a machine with a future clock.
Related errors
- token is invalidated
- that's not even a token
- token is expired
- couldn't handle this token
- failed to refresh token: sub not match
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/4a0ab89bbc50d3ad.
Report an issue: GitHub.