AlistGo/alist · error
string(data)
Error message
string(data)
What it means
During Cloudreve OneDrive-policy upload, a chunk/callback HTTP response had a status outside {200, 201, 202} and the raw body is returned as the error text. The body is usually the server's or Microsoft Graph's error JSON/HTML, shown verbatim.
Source
Thrown at drivers/cloudreve/util.go:356
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("{}")
}, nil)
}
func (d *Cloudreve) upS3(ctx context.Context, stream model.FileStreamer, u UploadInfo, up driver.UpdateProgress) error {
var finish int64 = 0
var chunk int = 0
var etags []string
DEFAULT := int64(u.ChunkSize)View on GitHub (pinned to 843d9dc814)
Solutions
- Retry the upload as a new OneDrive session — expired upload URLs and stale ranges are the dominant cause.
- For 429 responses, wait and retry later; OneDrive throttles aggressive chunk uploads.
- Increase chunk size or reduce parallelism so the session completes within its lifetime.
- Read the returned body — it usually contains Graph's code/message pinpointing the exact failure.
Defensive patterns
Strategy: try-catch
Type guard
func isGraphErrorBody(body string) bool {
return strings.Contains(body, "\"error\"") || strings.Contains(body, "service_unavailable")
} Try / catch
data, _ := io.ReadAll(res.Body)
if res.StatusCode != 200 && res.StatusCode != 201 && res.StatusCode != 202 {
var g struct{ Error struct{ Code, Message string } }
if json.Unmarshal(data, &g) == nil && g.Error.Code != "" {
return fmt.Errorf("onedrive upload %s: %s", g.Error.Code, g.Error.Message)
}
return errors.New(string(data))
} Prevention
- Finish OneDrive upload sessions within their ~15-minute lifetime
- Honor 429 Retry-After instead of hammering
- Parse Graph error JSON from the body before surfacing raw text
When it happens
Trigger: upOneDrive loop: after PUTting a chunk to the OneDrive upload URL (or when a proxy answers), res.StatusCode is e.g. 416/409/429 (not 5xx, which would retry). The body is read and returned untouched.
Common situations: Chunk offsets out of range for the session (416 Requested Range Not Satisfiable) after a resume; OneDrive upload URL expired (sessions live ~15 minutes); 429 throttling without Retry-After being honored; corporate proxy returning an HTML error page.
Related errors
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/9658e84dcd49db0b.
Report an issue: GitHub.