{"record":{"id":"b0e580eef823e413","repo":"AlistGo/alist","slug":"upload-request-failed-w","errorCode":null,"errorMessage":"upload request failed: %w","messagePattern":"upload request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao/util.go","lineNumber":655,"sourceCode":"\t\t\"X-Storage-U\":   d.UserId,\n\t\t\"Authorization\": storeInfo.Auth,\n\t})\n\n\tif method == http.MethodPost {\n\t\treq.SetHeader(\"Content-Type\", \"text/plain;charset=UTF-8\")\n\t}\n\n\tif callback != nil {\n\t\tcallback(req)\n\t}\n\n\tif resp != nil {\n\t\treq.SetResult(resp)\n\t}\n\n\tres, err := req.Execute(method, uploadUrl)\n\tif err != nil && err != io.EOF {\n\t\treturn nil, fmt.Errorf(\"upload request failed: %w\", err)\n\t}\n\n\treturn res.Body(), nil\n}\n\n// 初始化分片上传\nfunc (d *Doubao) initMultipartUpload(config *UploadConfig, uploadUrl string, storeInfo StoreInfo) (uploadId string, err error) {\n\tuploadResp := UploadResp{}\n\n\t_, err = d.uploadRequest(uploadUrl, http.MethodPost, storeInfo, func(req *resty.Request) {\n\t\treq.SetQueryParams(map[string]string{\n\t\t\t\"uploadmode\": \"part\",\n\t\t\t\"phase\":      \"init\",\n\t\t})\n\t}, &uploadResp)\n\n\tif err != nil {\n\t\treturn uploadId, err","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao/util.go#L637-L673","documentation":"Low-level transport error from the Doubao driver's shared uploadRequest helper: resty's req.Execute failed with something other than io.EOF (which is tolerated because the upload endpoints sometimes return empty bodies). This is the generic network/HTTP failure underneath every upload step (init, part, finish, commit).","triggerScenarios":"Any uploadRequest call (POST with part/transfer/finish/commit phases to the upload host) where the TCP/TLS connection fails, times out after UploadTimeout, the host header resolution fails (strings.Split(uploadUrl, \"/\")[2] yields a bad Host), or the server resets the connection.","commonSituations":"Slow or unstable network during large multipart uploads, upload host blocked by firewall/GFW-adjacent filtering, forced HTTP/1.1 + DisableKeepAlives interacting badly with middleboxes, DNS issues, or an upload URL that has expired between fetching upload config and using it.","solutions":["Retry the operation — transient network failures usually clear; the caller _retryOperation already retries, so persistent failure means a real connectivity issue","Check the wrapped error: timeouts suggest raising UploadTimeout for large parts; connection refused/DNS errors suggest firewall or DNS problems","Verify the uploadUrl from the upload config is still valid (they can expire); re-fetch upload config","Test reachability of the upload host from the host running OpenList","If behind a proxy, ensure it permits large POST bodies to the video CDN host"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// sanity-check the upload URL before use\nu, err := url.Parse(uploadUrl)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid upload url: %q\", uploadUrl)\n}","typeGuard":null,"tryCatchPattern":"// _retryOperation already retries; add outer backoff for persistent transport errors\nif err := operation(); err != nil {\n    if isTransportErr(err) { // net.Error, timeouts, connection reset\n        time.Sleep(backoff)\n        return operation()\n    }\n    return err\n}","preventionTips":["Ensure the host running OpenList can reach the Doubao upload/CDN hosts directly","Keep parts comfortably below UploadTimeout throughput; shrink chunk size on slow links","Exclude upload traffic from body-inspecting proxies"],"tags":["doubao","network","upload","resty","timeout","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}