hyperledger/fabric · error
collection config package for %s chaincode is not provided
Error message
collection config package for %s chaincode is not provided
What it means
During private data dissemination, the distributor looks up the collection config package for each namespace in the tx's private write set. If the caller-supplied CollectionConfigs map has no entry for a namespace, dissemination cannot proceed, so computeDisseminationPlan aborts with this error.
Source
Thrown at gossip/privdata/distributor.go:166
}
type dissemination struct {
msg *protoext.SignedGossipMessage
criteria gossipgossip.SendCriteria
}
func (d *distributorImpl) computeDisseminationPlan(txID string,
privDataWithConfig *transientstore.TxPvtReadWriteSetWithConfigInfo,
blkHt uint64,
) ([]*dissemination, error) {
privData := privDataWithConfig.PvtRwset
var disseminationPlan []*dissemination
for _, pvtRwset := range privData.NsPvtRwset {
namespace := pvtRwset.Namespace
configPackage, found := privDataWithConfig.CollectionConfigs[namespace]
if !found {
d.logger.Error("Collection config package for", namespace, "chaincode is not provided")
return nil, errors.New(fmt.Sprint("collection config package for", namespace, "chaincode is not provided"))
}
for _, collection := range pvtRwset.CollectionPvtRwset {
colCP, err := d.getCollectionConfig(configPackage, collection)
collectionName := collection.CollectionName
if err != nil {
d.logger.Error("Could not find collection access policy for", namespace, " and collection", collectionName, "error", err)
return nil, errors.WithMessage(err, fmt.Sprint("could not find collection access policy for", namespace, " and collection", collectionName, "error", err))
}
colAP, err := d.AccessPolicy(colCP, d.chainID)
if err != nil {
d.logger.Error("Could not obtain collection access policy, collection name", collectionName, "due to", err)
return nil, errors.Wrap(err, fmt.Sprint("Could not obtain collection access policy, collection name", collectionName, "due to", err))
}
colFilter := colAP.AccessFilter()
if colFilter == nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure CollectionConfigs is populated for every namespace in NsPvtRwset before calling Distribute
- Check that the collection config for the chaincode is committed on the channel and cached on this peer
- Verify chaincode/namespace names match exactly between the tx rwset and the config map
Example fix
// before
privDataWithConfig := &privdata.PrivateDataWithConfig{NsPvtRwset: rwset, CollectionConfigs: partialConfigs}
// after
for _, ns := range rwset.NsPvtRwset {
if _, ok := partialConfigs[ns.Namespace]; !ok { /* fetch config or skip */ }
} Defensive patterns
Strategy: validation
Validate before calling
for _, ns := range privData.NsPvtRwset {
if _, ok := privDataWithConfig.CollectionConfigs[ns.Namespace]; !ok {
return fmt.Errorf("missing collection config for namespace %s", ns.Namespace)
}
} Prevention
- Always build CollectionConfigs from the ledger for every namespace in the rwset
- Log and assert namespace coverage before calling Distribute
When it happens
Trigger: Distribute (via computeDisseminationPlan) is called with a privdata object whose CollectionConfigs map lacks a key for a namespace present in NsPvtRwset — e.g. the endorser/config cache did not return configs for that chaincode.
Common situations: Chaincode renamed or namespace mismatch between the rwset and the configs fetched from the ledger; collection config not yet committed/available on this peer; upstream code building privData omitted the namespace.
Related errors
- Could not obtain collection access policy, collection name %
- No collection access policy filter computed for %v
- required to disseminate to at least %d peers, but know of on
- Failed disseminating %d out of %d private dissemination plan
- Empty membership
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/80aa776316993fe9.
Report an issue: GitHub.