hyperledger/fabric · error

error unmarshalling compositeKV to collection config

Error message

error unmarshalling compositeKV to collection config

What it means

compositeKVToCollectionConfig failed to proto.Unmarshal the stored value into a CollectionConfigPackage — the persisted collection config entry under the confighistory namespace is corrupted or in an unexpected format.

Source

Thrown at core/ledger/confighistory/mgr.go:295

}

func prepareDBBatch(batch *batch, chaincodeCollConfigs map[string]*peer.CollectionConfigPackage, committingBlockNum uint64) error {
	for ccName, collConfig := range chaincodeCollConfigs {
		key := constructCollectionConfigKey(ccName)
		var configBytes []byte
		var err error
		if configBytes, err = proto.Marshal(collConfig); err != nil {
			return errors.WithStack(err)
		}
		batch.add(collectionConfigNamespace, key, committingBlockNum, configBytes)
	}
	return nil
}

func compositeKVToCollectionConfig(compositeKV *compositeKV) (*ledger.CollectionConfigInfo, error) {
	conf := &peer.CollectionConfigPackage{}
	if err := proto.Unmarshal(compositeKV.value, conf); err != nil {
		return nil, errors.Wrap(err, "error unmarshalling compositeKV to collection config")
	}
	return &ledger.CollectionConfigInfo{
		CollectionConfig:   conf,
		CommittingBlockNum: compositeKV.blockNum,
	}, nil
}

func constructCollectionConfigKey(chaincodeName string) string {
	return chaincodeName + "~collection" // collection config key as in version 1.2 and we continue to use this in order to be compatible with existing data
}

func extractPublicUpdates(stateUpdates ledger.StateUpdates) map[string][]*kvrwset.KVWrite {
	m := map[string][]*kvrwset.KVWrite{}
	for ns, updates := range stateUpdates {
		m[ns] = updates.PublicUpdates
	}
	return m
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the leveldb entry for corruption
  2. Rebuild config history or re-commit collection configs if the store is damaged

Example fix

// before
batch.Put(key, rawCollectionConfigJSON) // wrong format stored
// after
conf := &peer.CollectionConfigPackage{Config: configs}
batch.Put(key, protoutil.MarshalOrPanic(conf))
Defensive patterns

Strategy: validation

Validate before calling

conf := &peer.CollectionConfigPackage{}
if err := proto.Unmarshal(value, conf); err != nil {
    return fmt.Errorf("stored collection config is corrupt: %w", err)
}

Type guard

func isCollectionConfigPackage(b []byte) bool {
    conf := &peer.CollectionConfigPackage{}
    return proto.Unmarshal(b, conf) == nil
}

Try / catch

info, err := mgr.MostRecentCollectionConfigBelow(blockNum, ns, coll)
if err != nil && strings.Contains(err.Error(), "error unmarshalling compositeKV to collection config") {
    // rebuild config history from snapshot or re-import; treat DB as corrupt
}

Prevention

When it happens

Trigger: MostRecentCollectionConfigBelow reads an entry whose stored bytes fail proto.Unmarshal — corrupt DB values, values written by an incompatible schema version, or a non-config value written under the config-history namespace.

Common situations: LevelDB corruption after unclean shutdown; fabric version upgrades changing proto definitions; manual tampering or a bad import that stored wrong bytes.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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