hyperledger/fabric · error

error reading multipart data

Error message

error reading multipart data

What it means

While iterating the multipart response from CouchDB, the JSON part (Content-Type application/json) is read with io.ReadAll. This error wraps a read failure of the JSON part body, indicating the document payload could not be fully read from the stream.

Source

Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go:775

	// 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")
		contentDispositionParts := strings.Split(p.Header.Get("Content-Disposition"), ";")

		if strings.TrimSpace(contentDispositionParts[0]) != "attachment" {
			continue
		}

		switch p.Header.Get("Content-Encoding") {
		case "gzip": // See if the part is gzip encoded

			var respBody []byte

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Retry the query; transient stream failures typically clear on retry
  2. Check network path (proxies, LBs) for body size limits or idle timeouts and raise them
  3. Inspect CouchDB logs for errors/restarts coinciding with the failure
  4. Reduce batch sizes or document size if large payloads correlate with failures

Example fix

// before
docs, _, err := client.BatchRetrieveDocuments(keys)
// after
if err != nil && strings.Contains(err.Error(), "error reading multipart") {
    time.Sleep(500 * time.Millisecond)
    docs, _, err = client.BatchRetrieveDocuments(keys) // retry once
}
Defensive patterns

Strategy: retry

Validate before calling

resp, err := http.Head(couchURL + "/" + dbName)
if err != nil || resp.StatusCode != 200 { return errors.New("CouchDB/database not reachable") }

Try / catch

if err != nil && strings.Contains(err.Error(), "error reading multipart data") {
    if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) {
        time.Sleep(time.Second)
        return retry(...) // truncated stream: retry the read
    }
    return err
}

Prevention

When it happens

Trigger: BatchRetrieveDocuments encountering a broken/truncated response stream while reading the JSON portion of a document: connection reset mid-read, CouchDB closing the connection, or timeouts.

Common situations: Large documents exceeding proxy body limits; network instability to CouchDB; CouchDB restarting during bulk document retrieval.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/45b079751870a6fc. Report an issue: GitHub.