AlistGo/alist · error
failed to decode jwt token
Error message
failed to decode jwt token
What it means
Thrown by getSub() in the Aliyundrive Open driver when the JWT payload segment cannot be base64-decoded. The driver uses base64.RawStdEncoding.DecodeString on segments[1]; if the payload contains URL-safe characters ('-','_') or padding, standard decoding fails.
Source
Thrown at drivers/aliyundrive_open/util.go:163
}
newSub, err := getSub(refresh)
if err != nil {
return "", "", err
}
if curSub != newSub {
return "", "", errors.New("failed to refresh token: sub not match")
}
return refresh, access, nil
}
func getSub(token string) (string, error) {
segments := strings.Split(token, ".")
if len(segments) != 3 {
return "", errors.New("not a jwt token because of invalid segments")
}
bs, err := base64.RawStdEncoding.DecodeString(segments[1])
if err != nil {
return "", errors.New("failed to decode jwt token")
}
return utils.Json.Get(bs, "sub").ToString(), nil
}
func (d *AliyundriveOpen) refreshToken(ctx context.Context) error {
if d.ref != nil {
return d.ref.refreshToken(ctx)
}
refresh, access, err := d._refreshToken(ctx)
for i := 0; i < 3; i++ {
if err == nil {
break
}
if rateLimitErr, ok := err.(*refreshRateLimitError); ok {
wait := rateLimitErr.retryAfter
if wait <= 0 {
wait = time.Duration(i+1) * 2 * time.Second
}View on GitHub (pinned to 843d9dc814)
Solutions
- Inspect the token's middle segment manually: echo '<payload>' | base64 -d vs base64 -d with urlsafe translation to confirm the encoding
- Regenerate the refresh token via the official OAuth flow so a current, well-formed token is stored
- Update the alist driver to a version where getSub handles base64.URL encoding if the provider changed format
Example fix
// before (util.go)
bs, err := base64.RawStdEncoding.DecodeString(segments[1])
// after: tolerate both encodings
seg := strings.NewReplacer("-", "+", "_", "/").Replace(segments[1])
bs, err := base64.RawStdEncoding.DecodeString(seg) Defensive patterns
Strategy: validation
Validate before calling
func tryDecodeJWTPayload(seg string) ([]byte, error) {
if bs, err := base64.RawStdEncoding.DecodeString(seg); err == nil { return bs, nil }
if bs, err := base64.RawURLEncoding.DecodeString(seg); err == nil { return bs, nil }
return nil, errors.New("undecodable jwt payload")
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to decode jwt token") { seg := tokenSeg1; if _, e2 := base64.RawURLEncoding.DecodeString(seg); e2 == nil { /* encoding variant: handle urlsafe */ } } Prevention
- Treat base64 decode failure as a signal the token format changed
- Normalize -/_ before RawStdEncoding decode
- Keep the driver updated when providers rotate token formats
When it happens
Trigger: refreshTokenWithPost calls getSub(d.RefreshToken) or getSub(refresh) where the token's middle segment is base64url-encoded (RFC 7515 style, common for JWS tokens) rather than raw standard base64, or the segment is otherwise malformed/truncated.
Common situations: Aliyun changed or issues tokens signed with a different encoding variant; the token was truncated when copied into storage config; a proxy mangled the token response body.
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
- not a jwt token because of invalid segments
- failed to refresh token: refresh token is empty
- failed to refresh token: sub not match
- e.Message
- token is invalidated
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/b7161da4c29fad58.
Report an issue: GitHub.