AlistGo/alist · error

failed to refresh token: %w

Error message

failed to refresh token: %w

What it means

During getUploadConfig, the Doubao backend returned error code 100028 (upload token/credentials expired). The driver attempted to re-fetch the upload token via initUploadToken, and that re-fetch itself failed; the %w wraps the initUploadToken error. The upload cannot proceed without valid STS credentials.

Source

Thrown at drivers/doubao/util.go:388

		_, err := d.requestApi(uploadUrl, http.MethodGet, tokenType, func(req *resty.Request) {
			req.SetQueryParams(params)
		}, &configResp)
		if err != nil {
			return err
		}

		if configResp.ResponseMetadata.Error.Code == "" {
			*upConfig = configResp.Result
			return nil
		}

		// 100028 凭证过期
		if configResp.ResponseMetadata.Error.CodeN == 100028 && !tokenRefreshed {
			log.Debugln("[doubao] Upload token expired, re-fetching...")
			newToken, err := d.initUploadToken()
			if err != nil {
				return fmt.Errorf("failed to refresh token: %w", err)
			}

			d.UploadToken = newToken
			tokenRefreshed = true
			uploadUrl, params = configureParams()

			return retry.Error{errors.New("token refreshed, retry needed")}
		}

		return fmt.Errorf("get upload_config failed: %s", configResp.ResponseMetadata.Error.Message)
	})

	return err
}

// uploadNode 上传 文件信息
func (d *Doubao) uploadNode(uploadConfig *UploadConfig, dir model.Obj, file model.FileStreamer, dataType string) (UploadNodeResp, error) {
	reqUuid := uuid.New().String()

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-login: update the cookie/credentials in the Doubao driver config, then retry the upload (most common fix — the refresh uses the same dead session)
  2. If the wrapped error mentions rate limiting, back off and retry after a minute
  3. Restart the mount/process to clear stale in-memory UploadToken state after credential rotation

Example fix

// before
newToken, err := d.initUploadToken()
if err != nil {
	return fmt.Errorf("failed to refresh token: %w", err)
}
// after — make the auth root cause explicit
newToken, err := d.initUploadToken()
if err != nil {
	return fmt.Errorf("failed to refresh expired upload token (session cookie likely expired, re-login): %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

if d.Cookie == "" || cookieAge(d.Cookie) > sessionTTL {
	return errors.New("doubao session cookie stale — re-login before upload")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to refresh token") {
	// root cause is almost always the session cookie: reconfigure and retry whole upload
	return reloginThenRetryUpload()
}

Prevention

When it happens

Trigger: initUploadToken fails because the underlying session cookie is expired/invalid (the same stale credentials that caused 100028), the account is rate-limited, or the token endpoint is temporarily unavailable. The tokenRefreshed guard means only one refresh attempt happens per retry cycle.

Common situations: Long-running mounts where the login cookie expired while the upload token also lapsed — refresh needs a valid session but the session is the broken piece; concurrent uploads racing the single token refresh.

Related errors


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