AlistGo/alist · error
upload failed after %d retries due to server errors, error %
Error message
upload failed after %d retries due to server errors, error %d
What it means
Fatal retry exhaustion in Cloudreve's OneDrive-mediated upload (upOneDrive). Chunks are PUT directly to the OneDrive upload session URL; HTTP 500-504 responses are retried with exponential backoff. When retries exceed maxRetries, the loop aborts with this message, embedding the last HTTP status code.
Source
Thrown at drivers/cloudreve/util.go:348
return err
}
req = req.WithContext(ctx)
req.ContentLength = byteSize
// req.Header.Set("Content-Length", strconv.Itoa(int(byteSize)))
req.Header.Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", finish, finish+byteSize-1, stream.GetSize()))
req.Header.Set("User-Agent", d.getUA())
finish += byteSize
res, err := base.HttpClient.Do(req)
if err != nil {
return err
}
// https://learn.microsoft.com/zh-cn/onedrive/developer/rest-api/api/driveitem_createuploadsession
switch {
case res.StatusCode >= 500 && res.StatusCode <= 504:
retryCount++
if retryCount > maxRetries {
res.Body.Close()
return fmt.Errorf("upload failed after %d retries due to server errors, error %d", maxRetries, res.StatusCode)
}
backoff := time.Duration(1<<retryCount) * time.Second
utils.Log.Warnf("[Cloudreve-OneDrive] server errors %d while uploading, retrying after %v...", res.StatusCode, backoff)
time.Sleep(backoff)
case res.StatusCode != 201 && res.StatusCode != 202 && res.StatusCode != 200:
data, _ := io.ReadAll(res.Body)
res.Body.Close()
return errors.New(string(data))
default:
res.Body.Close()
retryCount = 0
finish += byteSize
up(float64(finish) * 100 / float64(stream.GetSize()))
}
}
// 上传成功发送回调请求
return d.request(http.MethodPost, "/callback/onedrive/finish/"+u.SessionID, func(req *resty.Request) {
req.SetBody("{}")View on GitHub (pinned to 843d9dc814)
Solutions
- Retry the whole upload after a wait — transient OneDrive 5xx storms usually clear
- Increase proxy read/write timeouts (or bypass the proxy for upload URLs) so chunk PUTs are not converted into 504s
- Check OneDrive service status and the Cloudreve session's validity; restart the upload to get a fresh session if it expired
- Raise maxRetries or use smaller chunks so each retry window is shorter
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: confirm the OneDrive session URL is alive with a cheap 0-byte request if supported, and check proxy timeouts > chunk transfer time
Try / catch
if err := d.upOneDrive(ctx, stream, u, up); err != nil {
if strings.Contains(err.Error(), "retries due to server errors") {
// session may be stale or OneDrive degraded: get a fresh session and retry once
u2, err2 := d.getUploadInfo(ctx, stream)
if err2 == nil {
err = d.upOneDrive(ctx, stream, u2, up)
}
}
} Prevention
- Set reverse-proxy timeouts above worst-case chunk upload duration
- Retry whole uploads (fresh session) rather than extending per-chunk retries indefinitely
- Watch OneDrive status pages during incident windows and defer bulk uploads
When it happens
Trigger: Every chunk PUT to the OneDrive upload URL returns a 5xx status (500-504) more than maxRetries times consecutively: OneDrive service degradation, the upload session expired server-side (some 5xx masks are actually session-invalid), or an intermediary proxy manufacturing 5xx responses.
Common situations: OneDrive outages or throttling during large uploads; a reverse proxy in front of Cloudreve timing out and returning 502/504 per chunk; slow networks where each chunk exceeds proxy timeouts.
Related errors
- upload failed after %d retries due to server errors, error %
- upload failed after %d retries due to server errors, error:
- string(data)
- up status: %d, error: %s
- upload failed after %d retries due to server errors, error:
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/92ba08455d521f28.
Report an issue: GitHub.