hyperledger/fabric · error

failed to unmarshal channel metadata

Error message

failed to unmarshal channel metadata

What it means

decodeChannelMetadata parses the channel metadata JSON stored in CouchDB back into a channelMetadata struct. Failure means the stored metadata document is corrupt or not in the expected schema, wrapped as 'failed to unmarshal channel metadata'; readChannelMetadata then fails.

Source

Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go:243

		return nil, err
	}
	return &version.Height{BlockNum: savepointDoc.BlockNum, TxNum: savepointDoc.TxNum}, nil
}

func encodeChannelMetadata(metadataDoc *channelMetadata) (*couchDoc, error) {
	metadataJSON, err := json.Marshal(metadataDoc)
	if err != nil {
		err = errors.Wrap(err, "failed to marshal channel metadata")
		logger.Errorf("%+v", err)
		return nil, err
	}
	return &couchDoc{jsonValue: metadataJSON, attachments: nil}, nil
}

func decodeChannelMetadata(couchDoc *couchDoc) (*channelMetadata, error) {
	metadataDoc := &channelMetadata{}
	if err := json.Unmarshal(couchDoc.jsonValue, &metadataDoc); err != nil {
		err = errors.Wrap(err, "failed to unmarshal channel metadata")
		logger.Errorf("%+v", err)
		return nil, err
	}
	return metadataDoc, nil
}

type dataformatInfo struct {
	Version string `json:"Version"`
}

func encodeDataformatInfo(dataFormatVersion string) (*couchDoc, error) {
	var err error
	dataformatInfo := &dataformatInfo{
		Version: dataFormatVersion,
	}
	dataformatInfoJSON, err := json.Marshal(dataformatInfo)
	if err != nil {
		err = errors.Wrapf(err, "failed to marshal dataformatInfo [%#v]", dataformatInfo)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect and correct the channel metadata document in CouchDB (it should contain the data format version field)
  2. Restore the state database from a valid backup
  3. If unrecoverable, rebuild the ledger database so metadata is rewritten at open time

Example fix

// before (corrupt doc)
{"DataFormatVersion": 2.5}
// after
{"DataFormatVersion": "2.0"}
Defensive patterns

Strategy: try-catch

Validate before calling

func validChannelMetadataJSON(b []byte) bool {
    var m struct{ DataFormatVersion string }
    return json.Unmarshal(b, &m) == nil
}

Try / catch

md, err := decodeChannelMetadata(doc)
if err != nil {
    return nil, fmt.Errorf("channel metadata corrupt; restore DB from backup: %w", err)
}

Prevention

When it happens

Trigger: readChannelMetadata fetches the channel metadata couchDoc and its jsonValue cannot be unmarshaled into channelMetadata (e.g. wrong field types, non-JSON content, wrong document retrieved).

Common situations: Manual modification of the metadata document in CouchDB, restoring databases from backups of a different Fabric version, or accidental overwrites by external tooling.

Related errors


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