hyperledger/fabric · error

error reading gzip data

Error message

error reading gzip data

What it means

After successfully opening a gzip reader for a compressed CouchDB attachment part, io.ReadAll(gr) failed while decompressing the body. This means the gzip stream started validly but was corrupt or truncated partway through.

Source

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

		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

			gr, err := gzip.NewReader(p)
			if err != nil {
				return nil, "", errors.Wrap(err, "error creating gzip reader")
			}
			respBody, err = io.ReadAll(gr)
			if err != nil {
				return nil, "", errors.Wrap(err, "error reading gzip data")
			}

			couchdbLogger.Debugf("[%s] Retrieved attachment data", dbclient.dbName)
			attachment.AttachmentBytes = respBody
			attachment.Length = uint64(len(attachment.AttachmentBytes))
			attachment.Name = p.FileName()
			attachments = append(attachments, attachment)

		default:

			// retrieve the data,  this is not gzip
			partdata, err := io.ReadAll(p)
			if err != nil {
				return nil, "", errors.Wrap(err, "error reading multipart data")
			}
			couchdbLogger.Debugf("[%s] Retrieved attachment data", dbclient.dbName)
			attachment.AttachmentBytes = partdata
			attachment.Length = uint64(len(attachment.AttachmentBytes))

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-fetch the attachment; if the error persists, the stored data is corrupt
  2. Restore the affected document/attachment from backup or re-upload it via the chaincode
  3. Run integrity checks on CouchDB storage (disk health, database compaction)
  4. Check for intermediaries truncating large responses and raise body limits

Example fix

// before (store unverified compressed bytes)
attachment.AttachmentBytes = compressedBytes
// after (verify before storing)
zr, err := gzip.NewReader(bytes.NewReader(compressedBytes))
if err != nil || len(compressedBytes) == 0 {
    return errors.New("refusing to store invalid/truncated gzip attachment")
}
attachment.AttachmentBytes = compressedBytes
Defensive patterns

Strategy: try-catch

Validate before calling

zr, err := gzip.NewReader(bytes.NewReader(storedAttachment))
if err != nil { return errors.New("stored attachment is not valid gzip") }
if _, err := io.ReadAll(zr); err != nil { return errors.New("stored gzip attachment is truncated/corrupt") }

Try / catch

if err != nil && strings.Contains(err.Error(), "error reading gzip data") {
    return fmt.Errorf("truncated/corrupt gzip attachment: %w; re-upload attachment via chaincode", err)
}

Prevention

When it happens

Trigger: Reading a gzip-encoded attachment whose compressed bytes are truncated or corrupted: interrupted writes to CouchDB, disk corruption, or stream cut off by network failure.

Common situations: Partial attachment uploads; corrupted CouchDB database files after unclean shutdown; proxies truncating large compressed bodies.

Related errors


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