hyperledger/fabric · error

failed to marshal channel metadata

Error message

failed to marshal channel metadata

What it means

encodeChannelMetadata serializes the channelMetadata document (ledger metadata persisted in the CouchDB state database) to JSON. A failure is wrapped with 'failed to marshal channel metadata' and writeChannelMetadata aborts. As with the savepoint, this marshal of a simple struct should never fail in stock Fabric.

Source

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

		return nil, err
	}
	return &couchDoc{jsonValue: savepointDocJSON, attachments: nil}, nil
}

func decodeSavepoint(couchDoc *couchDoc) (*version.Height, error) {
	savepointDoc := &couchSavepointData{}
	if err := json.Unmarshal(couchDoc.jsonValue, &savepointDoc); err != nil {
		err = errors.Wrap(err, "failed to unmarshal savepoint data")
		logger.Errorf("%+v", err)
		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"`

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the wrapped cause in the Errorf log output
  2. Keep channelMetadata limited to JSON-serializable fields (strings, numbers)
  3. Rebuild with unmodified Fabric sources and retry the ledger operation

Example fix

// before
type channelMetadata struct {
    DataFormatVersion string
    Hooks map[string]func() // not serializable
}
// after
type channelMetadata struct {
    DataFormatVersion string
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := json.Marshal(metadataDoc); err != nil {
    return fmt.Errorf("channel metadata not serializable: %w", err)
}

Try / catch

doc, err := encodeChannelMetadata(md)
if err != nil {
    logger.Errorf("channel metadata encode failed: %+v", err)
    return nil, err
}

Prevention

When it happens

Trigger: writeChannelMetadata calls encodeChannelMetadata and json.Marshal fails on the channelMetadata struct being persisted.

Common situations: Custom modifications to channelMetadata adding non-serializable fields; corrupt toolchain or dependency substitutions.

Related errors


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