AlistGo/alist · error
wukong upload to tos failed: code=%d message=%s
Error message
wukong upload to tos failed: code=%d message=%s
What it means
Thrown by uploadToTOS after POSTing the file body directly to https://<host>/upload/v1/<storeURI>. The TOS upload endpoint responded with a code other than 2000 (minUploadSubmitSuccess). The storage layer (Volcengine TOS fronted by Wukong) rejected the transfer — commonly auth, expiry, or host issues.
Source
Thrown at drivers/wukong/driver.go:589
SetHeader("Host", host).
SetHeader("Referer", webReferer).
SetHeader("Origin", "https://pan.wkbrowser.com").
SetHeader("Authorization", auth).
SetHeader("Content-Type", "application/octet-stream").
SetHeader("Content-Crc32", crc32Hex).
SetHeader("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, url.QueryEscape(fileName))).
SetHeader("Content-Length", strconv.FormatInt(size, 10)).
SetBody(body).
SetResult(&resp)
if storageUser != "" {
req.SetHeader("X-Storage-U", storageUser)
}
_, err := req.Post(uploadURL)
if err != nil {
return err
}
if resp.Code != minUploadSubmitSuccess {
return fmt.Errorf("wukong upload to tos failed: code=%d message=%s", resp.Code, resp.Message)
}
if resp.Data.Crc32 != "" && !strings.EqualFold(resp.Data.Crc32, crc32Hex) {
return fmt.Errorf("wukong upload to tos crc32 mismatch: local=%s remote=%s", crc32Hex, resp.Data.Crc32)
}
return nil
}
func (d *Wukong) uploadToTOSMultipart(ctx context.Context, host, storeURI, auth, storageUser string, tempFile model.File, size int64, up driver.UpdateProgress) error {
uploadID, err := d.initMultipartUpload(ctx, host, storeURI, auth, storageUser)
if err != nil {
return err
}
totalParts := int((size + multipartChunkSize - 1) / multipartChunkSize)
if totalParts <= 0 {
return errors.New("invalid multipart parts")
}
parts := make([]string, 0, totalParts)View on GitHub (pinned to 843d9dc814)
Solutions
- Retry via the multipart path (uploadToTOSMultipart) or re-run applyUploadInner to get fresh auth and hosts
- Ensure storageUser is set on the request when provided by ApplyUploadInner
- Confirm Content-Length matches the exact byte count being sent
- If resp.Message shows auth/expiry, mint a new auth token and restart the TOS transfer
Defensive patterns
Strategy: retry
Try / catch
if err := d.uploadToTOS(ctx, host, storeURI, auth, storageUser, tempFile, size); err != nil {
if strings.Contains(err.Error(), "auth") || strings.Contains(err.Error(), "expire") {
// re-apply for fresh auth, then retry once
return d.restartAndUpload(ctx)
}
return err
} Prevention
- Prefer multipart for large files so slow transfers can outlive token issues part-by-part
- Always forward X-Storage-U when the apply step provides it
- Set Content-Length exactly; mismatched lengths are rejected by the TOS front door
When it happens
Trigger: Authorization header (from ApplyUploadInner) expired during a slow upload; X-Storage-U missing when storageUser required; upload host from candidates unreachable/decommissioned; Content-Length/Content-Disposition malformed; body truncated.
Common situations: Large single-request uploads exceeding token validity; best-host selection picking a dead node (ClientBestHosts fallback not exercised); proxy or CDN in front mangling headers.
Related errors
- wukong upload to tos crc32 mismatch: local=%s remote=%s
- wukong init multipart upload failed: code=%d message=%s
- wukong multipart transfer failed: code=%d message=%s part=%d
- wukong multipart finish failed: code=%d message=%s
- wukong init multipart upload returns empty uploadid
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/741864c20944f3af.
Report an issue: GitHub.