AlistGo/alist · error
upload failed: http %d
Error message
upload failed: http %d
What it means
The POST to the upload server completed but returned an HTTP status other than 200. The response body is not included in the message, so the provider's explanation (auth failure, quota, size limit) is lost. Common codes: 401/403 (bad key), 413 (file too large), 5xx (server-side failure).
Source
Thrown at drivers/darkibox/driver.go:261
// 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{
Name: file.GetName(),
Size: file.GetSize(),
IsFolder: false,View on GitHub (pinned to 843d9dc814)
Solutions
- Map the status: 401/403 → refresh API key; 413 → split or compress the file / upgrade plan; 5xx → retry later
- Include res.Body() in the error (see exampleFix) so the provider's message is visible next time
- Verify fld_id still exists by listing the destination folder
Example fix
// before
if res.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("upload failed: http %d", res.StatusCode())
}
// after
if res.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("upload failed: http %d: %s", res.StatusCode(), strings.TrimSpace(string(res.Body())))
} Defensive patterns
Strategy: try-catch
Validate before calling
if file.GetSize() > d.maxFileSize() { // query provider limit
return errors.New("file exceeds provider size limit")
} Try / catch
var httpErr matcher // extract code from "upload failed: http %d"
if m := regexp.MustCompile(`upload failed: http (\d+)`).FindStringSubmatch(err.Error()); m != nil {
switch m[1] {
case "401", "403": reconfigureKey()
case "413": splitOrCompress()
case "502", "503": retryLater()
}
} Prevention
- Know the account's max file size before uploading
- Keep the API key valid for the whole upload session
- Treat 5xx as retryable, 4xx as configuration issues
When it happens
Trigger: Upload server rejects the multipart request: expired API key sent in the 'key' form field, file exceeds the account's size cap (413), invalid fld_id (404/400), or upload server overloaded (502/503).
Common situations: Free-tier accounts hitting max file size; key revoked between /upload/server and the POST; folder ID from a stale listing deleted server-side.
Related errors
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/a32180daaa49e780.
Report an issue: GitHub.