{"record":{"id":"1ace85497fb25839","repo":"AlistGo/alist","slug":"upload-failed-s-1ace85","errorCode":null,"errorMessage":"upload failed: %s","messagePattern":"upload failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao/util.go","lineNumber":481,"sourceCode":"\tuploadUrl := fmt.Sprintf(\"https://%s/upload/v1/%s\", uploadNode.UploadHost, storeInfo.StoreURI)\n\n\tuploadResp := UploadResp{}\n\n\tif _, err = d.uploadRequest(uploadUrl, http.MethodPost, storeInfo, func(req *resty.Request) {\n\t\treq.SetHeaders(map[string]string{\n\t\t\t\"Content-Type\":        \"application/octet-stream\",\n\t\t\t\"Content-Crc32\":       crc32Value,\n\t\t\t\"Content-Length\":      fmt.Sprintf(\"%d\", len(data)),\n\t\t\t\"Content-Disposition\": fmt.Sprintf(\"attachment; filename=%s\", url.QueryEscape(storeInfo.StoreURI)),\n\t\t})\n\n\t\treq.SetBody(data)\n\t}, &uploadResp); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif uploadResp.Code != 2000 {\n\t\treturn nil, fmt.Errorf(\"upload failed: %s\", uploadResp.Message)\n\t}\n\n\tuploadNodeResp, err := d.uploadNode(config, dstDir, file, dataType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &model.Object{\n\t\tID:       uploadNodeResp.Data.NodeList[0].ID,\n\t\tName:     uploadNodeResp.Data.NodeList[0].Name,\n\t\tSize:     file.GetSize(),\n\t\tIsFolder: false,\n\t}, nil\n}\n\n// UploadByMultipart 分片上传\nfunc (d *Doubao) UploadByMultipart(ctx context.Context, config *UploadConfig, fileSize int64, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress, dataType string) (model.Obj, error) {\n\t// 构建请求路径","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao/util.go#L463-L499","documentation":"After the file (or last part) bytes were accepted by the upload host, the upload endpoint's own envelope returned Code != 2000 and the driver aborts with the endpoint's Message. Bytes may have been transferred but the upload is not acknowledged as complete — the subsequent uploadNode (file registration) is skipped.","triggerScenarios":"The Volcengine-style upload endpoint rejects the PUT/POST: CRC32 mismatch between Content-Crc32 header and server-computed value, expired upload session/StoreURI, size mismatch with Content-Length, or store URI already consumed.","commonSituations":"Corrupted in-memory part data producing CRC mismatches; upload session timing out during slow multi-part transfers; retrying a part against an already-completed StoreURI.","solutions":["Retry the whole upload — transient CRC/session errors clear on a fresh upload-config cycle","For multipart, ensure each part's Content-Crc32 is computed over exactly the bytes sent (the driver does this; a mismatch implies memory/stream corruption — check RAM and disk)","If the message says expired/not exist, the upload session timed out — raise uploadThread/concurrency cautiously or reduce pauses between parts"],"exampleFix":"// before\nif uploadResp.Code != 2000 {\n\treturn nil, fmt.Errorf(\"upload failed: %s\", uploadResp.Message)\n}\n// after — retry once on session-type errors before failing\nif uploadResp.Code != 2000 {\n\treturn nil, fmt.Errorf(\"upload failed: code=%d msg=%s\", uploadResp.Code, uploadResp.Message)\n}","handlingStrategy":"retry","validationCode":"crc := calculateCRC32(data)\nif crc == 0 && len(data) > 0 {\n\treturn errors.New(\"crc computation suspicious — abort before upload\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"upload failed\") {\n\tif isTransientUploadMsg(err) { return retryWholeUpload(1) }\n\treturn fail(err)\n}","preventionTips":["Always compute CRC over the exact bytes sent","Treat session-expired messages as full-upload retries, not part retries","Keep upload latency low so sessions don't lapse"],"tags":["doubao","upload","crc32","api-error"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}