hyperledger/fabric · error

error creating gzip reader

Error message

error creating gzip reader

What it means

CouchDB attachments may be gzip-compressed (Content-Encoding: gzip). While decoding a multipart attachment, gzip.NewReader failed, meaning the part bytes are not a valid gzip stream despite being advertised as gzip.

Source

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

		}

		// 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

			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")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the attachment data in CouchDB directly (curl the attachment URL) to see if it is valid gzip
  2. Re-write the attachment or restore the affected document from a backup
  3. Check intermediaries (proxies) that might alter Content-Encoding or bodies
  4. Compare Fabric/CouchDB versions between environments if data was migrated

Example fix

// validation before storing
var buf bytes.Buffer
zw := gzip.NewWriter(&buf)
zw.Write(attachmentBytes)
zw.Close()
// confirm round-trip
zr, err := gzip.NewReader(bytes.NewReader(buf.Bytes()))
if err != nil { return errors.New("attachment gzip payload invalid") }
Defensive patterns

Strategy: validation

Validate before calling

br := bufio.NewReader(partBytes)
magic, _ := br.Peek(2)
if len(magic) < 2 || magic[0] != 0x1f || magic[1] != 0x8b {
    return errors.New("attachment bytes are not gzip despite gzip Content-Encoding")
}

Type guard

func isGzip(b []byte) bool {
    return len(b) >= 2 && b[0] == 0x1f && b[1] == 0x8b
}

Try / catch

if err != nil && strings.Contains(err.Error(), "error creating gzip reader") {
    return fmt.Errorf("attachment corrupted in CouchDB: %w; restore document from backup", err)
}

Prevention

When it happens

Trigger: Reading an attachment whose part claims Content-Encoding gzip but whose payload is corrupt, truncated, or not actually gzipped — e.g. data written by a different version/tooling or corrupted in storage.

Common situations: Corrupted attachments in the CouchDB database; proxy rewriting/compressing responses incorrectly; mismatch between how attachment was stored (compress:false) and read.

Related errors


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