AlistGo/alist · error

refresh token failed: %s

Error message

refresh token failed: %s

What it means

refreshToken posts to the token endpoint and throws when the response is an HTTP error, carries an OAuth-style error field, or the returned AccessToken is empty. The message picks the most informative detail available: ErrorDesc, then Error, then the raw body, then just the status code. Because tokens are only persisted after success, storage state is preserved.

Source

Thrown at drivers/guangyapan/driver.go:591

			"refresh_token": d.RefreshToken,
		}).
		SetResult(&out).
		Post("/v1/auth/token")
	if err != nil {
		return err
	}
	if resp.IsError() || out.Error != "" || strings.TrimSpace(out.AccessToken) == "" {
		errMsg := strings.TrimSpace(out.ErrorDesc)
		if errMsg == "" {
			errMsg = strings.TrimSpace(out.Error)
		}
		if errMsg == "" {
			errMsg = strings.TrimSpace(resp.String())
		}
		if errMsg == "" {
			errMsg = fmt.Sprintf("status=%d", resp.StatusCode())
		}
		return fmt.Errorf("refresh token failed: %s", errMsg)
	}

	d.AccessToken = strings.TrimSpace(out.AccessToken)
	if strings.TrimSpace(out.RefreshToken) != "" {
		d.RefreshToken = strings.TrimSpace(out.RefreshToken)
	}
	op.MustSaveDriverStorage(d)
	return nil
}

func (d *GuangYaPan) canSMSLogin() bool {
	return d.PhoneNumber != "" && d.VerifyCode != ""
}

func (d *GuangYaPan) loginBySMSCode(ctx context.Context) error {
	verificationID := strings.TrimSpace(d.VerificationID)
	if verificationID == "" {
		var err error

View on GitHub (pinned to 843d9dc814)

Solutions

  1. If errMsg says invalid_grant/expired: re-do SMS login (fill phone_number and a fresh verify_code, save storage).
  2. Retry once after a short delay for transient 5xx failures.
  3. Confirm the storage's refresh_token field was not manually edited or truncated.
Defensive patterns

Strategy: retry

Try / catch

if err := op.Retry(2, time.Second, func() error {
    return d.refreshToken(ctx)
}); err != nil {
    if strings.Contains(err.Error(), "invalid_grant") || strings.Contains(err.Error(), "expired") {
        // unrecoverable: require SMS re-login
        return errors.New("please re-login via SMS (fill verify_code)")
    }
    return err
}

Prevention

When it happens

Trigger: postAPI hits 401/403 and calls refreshToken with an expired/revoked RefreshToken; the provider rejects the grant (invalid_grant); or a successful-status response omits access_token.

Common situations: Storage unused for a long time so the refresh token rotated/expired; refresh token reused after another client already rotated it; account service temporarily failing.

Related errors


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