AlistGo/alist · error
upload failed: %w
Error message
upload failed: %w
What it means
The multipart POST of the file bytes to the upload server URL failed at the transport level (%w wraps a resty/network error). This happens before any status-code check — the request never completed successfully: DNS failure, connection reset, TLS error, or context cancellation.
Source
Thrown at drivers/darkibox/driver.go:258
return nil, fmt.Errorf("no upload server URL returned")
}
// Step 2: Upload the file to the upload server
reader := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
Reader: file,
UpdateProgress: up,
})
res, err := base.RestyClient.R().
SetContext(ctx).
SetMultipartField("file", file.GetName(), "", reader).
SetMultipartFormData(map[string]string{
"key": d.APIKey,
"fld_id": fldIDStr(folderID),
}).
Post(server.URL)
if err != nil {
return nil, fmt.Errorf("upload failed: %w", err)
}
if res.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("upload failed: http %d", res.StatusCode())
}
// Try to parse upload response to get the file code
var uploadResp uploadResult
if err := base.RestyClient.JSONUnmarshal(res.Body(), &uploadResp); err == nil && len(uploadResp.Files) > 0 {
uf := uploadResp.Files[0]
return &model.Object{
ID: encodeFileID(uf.FileCode),
Name: file.GetName(),
Size: file.GetSize(),
IsFolder: false,
}, nil
}
return &model.Object{View on GitHub (pinned to 843d9dc814)
Solutions
- If the wrapped error mentions context cancellation, the upload was aborted intentionally — not a bug
- Retry the upload; resty-level transport errors are usually transient
- Check connectivity to the specific upload server host returned by /upload/server (it may differ from the API domain)
- For repeated resets on large files, verify MTU/proxy settings or try a smaller test file to isolate size-related drops
Example fix
// before
res, err := base.RestyClient.R().
SetContext(ctx).
SetMultipartField("file", file.GetName(), "", reader).
Post(server.URL)
// after — SetRetryCount/RetryCondition can be set on a dedicated client for transient transport errors
res, err := base.RestyClient.R().
SetContext(ctx).
SetMultipartField("file", file.GetName(), "", reader).
Post(server.URL)
// (wrap Put's caller with retry for "upload failed: ... connection reset" messages) Defensive patterns
Strategy: retry
Validate before calling
parsed, err := url.Parse(server.URL)
if err != nil || parsed.Host == "" {
return nil, errors.New("upload server URL unusable")
} Try / catch
if err != nil && strings.Contains(err.Error(), "upload failed") {
if errors.Is(err, context.Canceled) { return err } // user abort: do not retry
return retryWithBackoff(ctx, upload, 3)
} Prevention
- Use resumable/retryable upload wrappers for large files
- Check egress to the upload host before big transfers
- Abort cleanly on context cancellation instead of retrying
When it happens
Trigger: resty Post() returns err on: context cancelled (user aborted upload), dial tcp timeout to the upload server host, TLS handshake failure, connection reset mid-transfer (often caused by the provider dropping large bodies), or reading from the limited stream erroring.
Common situations: Large uploads over unstable links; upload server host differs from apiBase and is blocked by firewall/GFW; proxy misconfiguration; user cancels the upload midway; disk read error while streaming the source file.
Related errors
- upload request failed: %w
- upload/download stream incomplete, possible network issue
- get upload server failed: %w
- no upload server URL returned
- upload failed: http %d
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/7b928e67304e4114.
Report an issue: GitHub.