{"record":{"id":"abea01300deaad4e","repo":"hyperledger/fabric","slug":"error-reading-next-multipart","errorCode":null,"errorMessage":"error reading next multipart","messagePattern":"error reading next multipart","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go","lineNumber":765,"sourceCode":"\tif !strings.HasPrefix(mediaType, \"multipart/\") {\n\t\tcouchDoc.jsonValue, err = io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrap(err, \"error reading response body\")\n\t\t}\n\n\t\treturn &couchDoc, revision, nil\n\t}\n\n\t// Handle as attachment.\n\t// Set up the multipart reader based on the boundary.\n\tmultipartReader := multipart.NewReader(resp.Body, params[\"boundary\"])\n\tfor {\n\t\tp, err := multipartReader.NextPart()\n\t\tif err == io.EOF {\n\t\t\tbreak // processed all parts\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrap(err, \"error reading next multipart\")\n\t\t}\n\n\t\tdefer p.Close()\n\n\t\tcouchdbLogger.Debugf(\"[%s] part header=%s\", dbclient.dbName, p.Header)\n\n\t\tif p.Header.Get(\"Content-Type\") == \"application/json\" {\n\t\t\tpartdata, err := io.ReadAll(p)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, \"\", errors.Wrap(err, \"error reading multipart data\")\n\t\t\t}\n\t\t\tcouchDoc.jsonValue = partdata\n\t\t\tcontinue\n\t\t}\n\n\t\t// Create an attachment structure and load it.\n\t\tattachment := &attachmentInfo{}\n\t\tattachment.ContentType = p.Header.Get(\"Content-Type\")","sourceCodeStart":747,"sourceCodeEnd":783,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go#L747-L783","documentation":"When reading a CouchDB document with attachments, BatchRetrieveDocuments/BatchUpdateDocuments parse CouchDB's multipart/mixed response. This error wraps a failure from multipartReader.NextPart(), meaning the multipart body from CouchDB was malformed or the connection broke mid-response.","triggerScenarios":"Reading documents (with include_docs/attachments) when CouchDB returns a truncated or invalid multipart body: network interruption, CouchDB crash/timeout mid-response, or an intermediary proxy mangling the response.","commonSituations":"Unstable network between peer and CouchDB; load balancer/proxy with aggressive timeouts; CouchDB under heavy load dropping connections; TLS termination issues.","solutions":["Verify connectivity to CouchDB (curl the _all_docs endpoint) and check CouchDB logs for errors at the same timestamp","Retry the failed query — multipart parse failures from transient network issues usually succeed on retry","Remove/increase proxy or load-balancer idle timeouts between peer and CouchDB","Check CouchDB health/resources (memory, max_connections) and scale if it is crashing mid-response"],"exampleFix":"// before\nclient, err := CreateCouchDBClient(...)\ndocs, _, err := client.BatchRetrieveDocuments(...)\n// after (add resilience)\nconst maxRetries = 3\nvar docs []*couchdb.CouchDoc\nfor i := 0; i < maxRetries; i++ {\n    docs, _, err = client.BatchRetrieveDocuments(...)\n    if err == nil { break }\n    time.Sleep(time.Duration(i+1) * time.Second)\n}","handlingStrategy":"retry","validationCode":"resp, err := http.Get(couchURL + \"/_all_dbs\")\nif err != nil || resp.StatusCode != 200 { return errors.New(\"CouchDB unreachable or unhealthy before query\") }","typeGuard":null,"tryCatchPattern":"docs, _, err := client.BatchRetrieveDocuments(keys)\nif err != nil && strings.Contains(err.Error(), \"error reading next multipart\") {\n    // transient stream failure: backoff and retry\n    time.Sleep(1 * time.Second)\n    docs, _, err = client.BatchRetrieveDocuments(keys)\n}","preventionTips":["Monitor CouchDB health/connectivity from the peer host","Avoid aggressive proxy/LB idle timeouts on the peer-CouchDB link","Keep CouchDB resourced to avoid crashes under load","Use retries with backoff for bulk document reads"],"tags":["couchdb","network","multipart","http"],"backgroundTag":"malformed-multipart-response","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}