AlistGo/alist · error

couldn't handle this token

Error message

couldn't handle this token

What it means

ParseToken's fallback inside the ValidationError branch: the JWT library reported a validation error that is neither Malformed, Expired, nor NotValidYet — typically a signature validation failure (ValidationErrorSignatureInvalid) from signing with a different key.

Source

Thrown at server/common/auth.go:57

}

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
}

func IsTokenInvalidated(tokenString string) bool {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-login to obtain a token signed by the current instance's key
  2. Pin the JWT secret in config so restarts do not rotate it
  3. Share the same secret across all instances that must verify each other's tokens

Example fix

# before (config.json)
"jwt_secret": ""  # regenerated each deploy -> old tokens fail

# after
"jwt_secret": "a-long-stable-random-value"
Defensive patterns

Strategy: try-catch

Try / catch

_, err := common.ParseToken(tok)
if err != nil && strings.Contains(err.Error(), "couldn't handle this token") {
	c.AbortWithStatusJSON(401, gin.H{"error": "token rejected"})
	return
}

Prevention

When it happens

Trigger: Verifying a token signed with a different SecretKey: alist restarted with a regenerated secret, a token from another instance/deployment, or a hand-forged signature.

Common situations: alist generates a random JWT secret on first run; wiping data or changing the secret invalidates all outstanding tokens. Multi-instance setups where instances do not share the secret.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/6c13e758e91a6e3c. Report an issue: GitHub.