fish2018/pansou · error
token cannot be empty
Error message
token cannot be empty
What it means
Sentinel validation error at the top of ValidateToken (util/jwt.go:42): raised when the token string argument is empty, meaning there is nothing to parse or verify. It indicates the caller passed a missing/blank credential (e.g. no Authorization header) rather than an invalid or expired token.
Solutions
- Check auth middleware: return 401 when the extracted token string is empty before calling ValidateToken
- Ensure clients send "Authorization: Bearer <token>" and the middleware parses the prefix correctly
- On the client, never send requests to protected endpoints without storing/attaching the token
Example fix
// before
claims, err := util.ValidateToken(tokenString, secret)
// after
if tokenString == "" {
c.AbortWithStatusJSON(401, gin.H{"error": "missing token"})
return
}
claims, err := util.ValidateToken(tokenString, secret) Defensive patterns
Strategy: validation
Validate before calling
if tokenString == "" { return errors.New("missing bearer token") } Try / catch
claims, err := util.ValidateToken(tokenString, secret)
if err != nil {
c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"})
return
} Prevention
- Reject requests missing Authorization header in middleware
- Parse the Bearer prefix defensively
- Return 401 (not 500) for missing tokens
When it happens
Trigger: 请求未携带 Authorization 头、Bearer 后为空串,或上游中间件在鉴权前就把空 token 传入校验函数。
Common situations: Client sends no Authorization header; header uses wrong scheme so prefix trimming yields empty string; token dropped by a proxy.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/090462f507fc3183.
Report an issue: GitHub.
Appendix: source
Thrown at util/jwt.go:42
expirationTime := time.Now().Add(expiry)
claims := &Claims{
Username: username,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(expirationTime),
IssuedAt: jwt.NewNumericDate(time.Now()),
Issuer: "pansou",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secret))
}
// ValidateToken 验证JWT token
func ValidateToken(tokenString string, secret string) (*Claims, error) {
if tokenString == "" {
return nil, errors.New("token cannot be empty")
}
if secret == "" {
return nil, errors.New("secret cannot be empty")
}
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
// 验证签名算法
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("unexpected signing method")
}
return []byte(secret), nil
})
if err != nil {
return nil, err
}View on GitHub (pinned to beaa561337)