{"record":{"id":"6d57ac103161d013","repo":"AlistGo/alist","slug":"failed-to-read-response-body-v","errorCode":null,"errorMessage":"failed to read response body: %v","messagePattern":"failed to read response body: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/mediafire/util.go","lineNumber":425,"sourceCode":"\treq.ContentLength = int64(len(unitData))\n\n\t/* fmt.Printf(\"Debug resumable upload request:\\n\")\n\tfmt.Printf(\"  URL: %s\\n\", req.URL.String())\n\tfmt.Printf(\"  Headers: %+v\\n\", req.Header)\n\tfmt.Printf(\"  Unit ID: %d\\n\", unitID)\n\tfmt.Printf(\"  Unit Size: %d\\n\", len(unitData))\n\tfmt.Printf(\"  Upload Key: %s\\n\", uploadKey)\n\tfmt.Printf(\"  Action Token: %s\\n\", actionToken) */\n\n\tres, err := base.HttpClient.Do(req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer res.Body.Close()\n\n\tbody, err := io.ReadAll(res.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read response body: %v\", err)\n\t}\n\n\t//fmt.Printf(\"MediaFire resumable upload response (status %d): %s\\n\", res.StatusCode, string(body))\n\n\tvar uploadResp struct {\n\t\tResponse struct {\n\t\t\tDoupload struct {\n\t\t\t\tKey string `json:\"key\"`\n\t\t\t} `json:\"doupload\"`\n\t\t\tResult string `json:\"result\"`\n\t\t} `json:\"response\"`\n\t}\n\n\tif err := json.Unmarshal(body, &uploadResp); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to parse response: %v\", err)\n\t}\n\n\tif res.StatusCode != 200 {","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/mediafire/util.go#L407-L443","documentation":"io.ReadAll on the response body of POST /upload/resumable.php failed while draining the upload unit acknowledgement. This is a transport-level failure mid-body: the connection dropped after headers were sent, or the body was cut off. The request itself may or may not have been processed server-side, which matters for resumable-upload correctness.","triggerScenarios":"Connection reset/timeout while MediaFire streams the (often large) JSON acknowledgement; proxy or reverse proxy truncating the response; TLS renegotiation mid-body; very slow networks where the client read deadline expires.","commonSituations":"Mobile or unstable networks uploading large units; corporate proxies with body-size or idle limits; MediaFire server-side connection churn during peak load; misconfigured HTTP client timeouts shorter than body transfer time.","solutions":["Retry the unit upload — the protocol is resumable and bitmap-tracked, so re-sending a unit is safe","Increase the shared HTTP client's timeout and TLS handshake timeout for large unit sizes","If consistently reproducible, capture whether a proxy sits between client and api.mediafire.com and relax its limits","Verify the upload key is still valid before retrying; if expired, re-run uploadCheck to get a new one"],"exampleFix":"// before\nbody, err := io.ReadAll(res.Body)\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to read response body: %v\", err)\n}\n\n// after\nbody, err := io.ReadAll(res.Body)\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to read response body (unit %d, status %d): %w\", unitID, res.StatusCode, err)\n}","handlingStrategy":"retry","validationCode":"// Ensure client timeouts accommodate unit-sized transfers\nif base.HttpClient.Timeout < time.Duration(unitSize)*time.Millisecond {\n    // use a per-request context deadline sized to the unit instead\n    ctx, cancel := context.WithTimeout(ctx, 10*time.Minute)\n    defer cancel()\n}","typeGuard":null,"tryCatchPattern":"// Safe retry: resumable protocol tolerates re-sent units\nerr := d.resumableUpload(...)\nfor attempt := 0; attempt < 3 && isTransient(err); attempt++ {\n    time.Sleep(time.Duration(attempt+1) * time.Second)\n    err = d.resumableUpload(...)\n}","preventionTips":["Size client timeouts to unit size and network speed","Send units sequentially or cap concurrency to avoid proxy resets","Verify upload key validity before retrying after long delays"],"tags":["mediafire","network","upload","io","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}