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: %s

What it means

Fatal retry exhaustion in Cloudreve's local/remote-protocol chunked upload (upRemote). Each chunk PUT is retried with exponential backoff (2^retryCount seconds) while the server keeps returning errors the code treats as server-side; after maxRetries consecutive failures the upload aborts with this message, embedding the last chunk error.

Source

Thrown at drivers/cloudreve/util.go:299

			var up Resp
			err = json.Unmarshal(body, &up)
			if err != nil {
				return err
			}
			if up.Code != 0 {
				return errors.New(up.Msg)
			}
			return nil
		}()
		if err == nil {
			retryCount = 0
			finish += byteSize
			up(float64(finish) * 100 / float64(stream.GetSize()))
			chunk++
		} else {
			retryCount++
			if retryCount > maxRetries {
				return fmt.Errorf("upload failed after %d retries due to server errors, error: %s", maxRetries, err)
			}
			backoff := time.Duration(1<<retryCount) * time.Second
			utils.Log.Warnf("[Cloudreve-Remote] server errors while uploading, retrying after %v...", backoff)
			time.Sleep(backoff)
		}
	}
	return nil
}

func (d *Cloudreve) upOneDrive(ctx context.Context, stream model.FileStreamer, u UploadInfo, up driver.UpdateProgress) error {
	uploadUrl := u.UploadURLs[0]
	var finish int64 = 0
	DEFAULT := int64(u.ChunkSize)
	retryCount := 0
	maxRetries := 3
	for finish < stream.GetSize() {
		if utils.IsCanceled(ctx) {
			return ctx.Err()

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Check the Cloudreve server's logs and its own storage policy health — the server-side error string in the message identifies the cause
  2. Free server disk space or fix the server's upstream storage credentials, then restart the upload
  3. Retry the upload when the server is healthy; split very large files or increase chunk size to reduce per-chunk failure windows
  4. If the session expired, obtain a fresh upload session (re-put) instead of continuing
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: verify the upload session and server health before chunking
if u.SessionID == "" || len(u.UploadURLs) == 0 {
    return errors.New("invalid upload session; request a new one before uploading")
}

Try / catch

err := d.upRemote(ctx, stream, u, up)
if err != nil && strings.Contains(err.Error(), "upload failed after") {
    // terminal after maxRetries inside; back off and restart the whole upload at most once
    time.Sleep(time.Minute)
    err = d.upRemote(ctx, stream, u, up)
}

Prevention

When it happens

Trigger: A Cloudreve upload session where every chunk request fails maxRetries+1 times in a row: Cloudreve backend returning 5xx or an error payload for each chunk (disk full on the server, upstream remote storage down, rate limiting), or the session expiring so each chunk PUT errors.

Common situations: Cloudreve server's own remote storage (OneDrive/S3 backing) is unavailable; server disk quota exhausted; uploading a very large file over an unstable connection where retry never succeeds before the session times out; older Cloudreve versions with chunked-upload bugs.

Related errors


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