hyperledger/fabric · error
error reading next multipart
Error message
error reading next multipart
What it means
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.
Source
Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go:765
if !strings.HasPrefix(mediaType, "multipart/") {
couchDoc.jsonValue, err = io.ReadAll(resp.Body)
if err != nil {
return nil, "", errors.Wrap(err, "error reading response body")
}
return &couchDoc, revision, nil
}
// Handle as attachment.
// Set up the multipart reader based on the boundary.
multipartReader := multipart.NewReader(resp.Body, params["boundary"])
for {
p, err := multipartReader.NextPart()
if err == io.EOF {
break // processed all parts
}
if err != nil {
return nil, "", errors.Wrap(err, "error reading next multipart")
}
defer p.Close()
couchdbLogger.Debugf("[%s] part header=%s", dbclient.dbName, p.Header)
if p.Header.Get("Content-Type") == "application/json" {
partdata, err := io.ReadAll(p)
if err != nil {
return nil, "", errors.Wrap(err, "error reading multipart data")
}
couchDoc.jsonValue = partdata
continue
}
// Create an attachment structure and load it.
attachment := &attachmentInfo{}
attachment.ContentType = p.Header.Get("Content-Type")View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
client, err := CreateCouchDBClient(...)
docs, _, err := client.BatchRetrieveDocuments(...)
// after (add resilience)
const maxRetries = 3
var docs []*couchdb.CouchDoc
for i := 0; i < maxRetries; i++ {
docs, _, err = client.BatchRetrieveDocuments(...)
if err == nil { break }
time.Sleep(time.Duration(i+1) * time.Second)
} Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Get(couchURL + "/_all_dbs")
if err != nil || resp.StatusCode != 200 { return errors.New("CouchDB unreachable or unhealthy before query") } Try / catch
docs, _, err := client.BatchRetrieveDocuments(keys)
if err != nil && strings.Contains(err.Error(), "error reading next multipart") {
// transient stream failure: backoff and retry
time.Sleep(1 * time.Second)
docs, _, err = client.BatchRetrieveDocuments(keys)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Unstable network between peer and CouchDB; load balancer/proxy with aggressive timeouts; CouchDB under heavy load dropping connections; TLS termination issues.
Related errors
- error reading multipart data
- http error calling couchdb
- failed to create target folder for connection.json: %s
- reading http response body: %s
- error reading response body
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/abea01300deaad4e.
Report an issue: GitHub.