{"record":{"id":"763eae8fb7325ded","repo":"hyperledger/fabric","slug":"error-unmarshalling-compositekv-to-collection-conf","errorCode":null,"errorMessage":"error unmarshalling compositeKV to collection config","messagePattern":"error unmarshalling compositeKV to collection config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/confighistory/mgr.go","lineNumber":295,"sourceCode":"}\n\nfunc prepareDBBatch(batch *batch, chaincodeCollConfigs map[string]*peer.CollectionConfigPackage, committingBlockNum uint64) error {\n\tfor ccName, collConfig := range chaincodeCollConfigs {\n\t\tkey := constructCollectionConfigKey(ccName)\n\t\tvar configBytes []byte\n\t\tvar err error\n\t\tif configBytes, err = proto.Marshal(collConfig); err != nil {\n\t\t\treturn errors.WithStack(err)\n\t\t}\n\t\tbatch.add(collectionConfigNamespace, key, committingBlockNum, configBytes)\n\t}\n\treturn nil\n}\n\nfunc compositeKVToCollectionConfig(compositeKV *compositeKV) (*ledger.CollectionConfigInfo, error) {\n\tconf := &peer.CollectionConfigPackage{}\n\tif err := proto.Unmarshal(compositeKV.value, conf); err != nil {\n\t\treturn nil, errors.Wrap(err, \"error unmarshalling compositeKV to collection config\")\n\t}\n\treturn &ledger.CollectionConfigInfo{\n\t\tCollectionConfig:   conf,\n\t\tCommittingBlockNum: compositeKV.blockNum,\n\t}, nil\n}\n\nfunc constructCollectionConfigKey(chaincodeName string) string {\n\treturn chaincodeName + \"~collection\" // collection config key as in version 1.2 and we continue to use this in order to be compatible with existing data\n}\n\nfunc extractPublicUpdates(stateUpdates ledger.StateUpdates) map[string][]*kvrwset.KVWrite {\n\tm := map[string][]*kvrwset.KVWrite{}\n\tfor ns, updates := range stateUpdates {\n\t\tm[ns] = updates.PublicUpdates\n\t}\n\treturn m\n}","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/confighistory/mgr.go#L277-L313","documentation":"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.","triggerScenarios":"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.","commonSituations":"LevelDB corruption after unclean shutdown; fabric version upgrades changing proto definitions; manual tampering or a bad import that stored wrong bytes.","solutions":["Inspect the leveldb entry for corruption","Rebuild config history or re-commit collection configs if the store is damaged"],"exampleFix":"// before\nbatch.Put(key, rawCollectionConfigJSON) // wrong format stored\n// after\nconf := &peer.CollectionConfigPackage{Config: configs}\nbatch.Put(key, protoutil.MarshalOrPanic(conf))","handlingStrategy":"validation","validationCode":"conf := &peer.CollectionConfigPackage{}\nif err := proto.Unmarshal(value, conf); err != nil {\n    return fmt.Errorf(\"stored collection config is corrupt: %w\", err)\n}","typeGuard":"func isCollectionConfigPackage(b []byte) bool {\n    conf := &peer.CollectionConfigPackage{}\n    return proto.Unmarshal(b, conf) == nil\n}","tryCatchPattern":"info, err := mgr.MostRecentCollectionConfigBelow(blockNum, ns, coll)\nif err != nil && strings.Contains(err.Error(), \"error unmarshalling compositeKV to collection config\") {\n    // rebuild config history from snapshot or re-import; treat DB as corrupt\n}","preventionTips":["Only store proto.Marshal(&peer.CollectionConfigPackage{...}) values in the history DB","Keep fabric versions/protos consistent across upgrades","Back up the confighistory DB before upgrades","Rebuild corrupted ledger data rather than patching individual values"],"tags":["fabric","leveldb","protobuf","unmarshal"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}