hyperledger/fabric · error

no configuration for collection %s found

Error message

no configuration for collection %s found

What it means

getCollectionConfig scans the CollectionConfigPackage for a static collection config whose name matches the collection in the private rwset. If none matches, it returns this error, aborting dissemination for that namespace.

Source

Thrown at gossip/privdata/distributor.go:213

			dPlan, err := d.disseminationPlanForMsg(colAP, colFilter, pvtDataMsg)
			if err != nil {
				return nil, errors.WithMessagef(err, "could not build private data dissemination plan for chaincode %s and collection %s", namespace, collectionName)
			}
			disseminationPlan = append(disseminationPlan, dPlan...)
		}
	}
	return disseminationPlan, nil
}

func (d *distributorImpl) getCollectionConfig(config *peer.CollectionConfigPackage, collection *rwset.CollectionPvtReadWriteSet) (*peer.CollectionConfig, error) {
	for _, c := range config.Config {
		if staticConfig := c.GetStaticCollectionConfig(); staticConfig != nil {
			if staticConfig.Name == collection.CollectionName {
				return c, nil
			}
		}
	}
	return nil, errors.New(fmt.Sprint("no configuration for collection", collection.CollectionName, "found"))
}

func (d *distributorImpl) disseminationPlanForMsg(colAP privdata.CollectionAccessPolicy, colFilter privdata.Filter, pvtDataMsg *protoext.SignedGossipMessage) ([]*dissemination, error) {
	var disseminationPlan []*dissemination

	routingFilter, err := d.gossipAdapter.PeerFilter(gossipCommon.ChannelID(d.chainID), func(signature api.PeerSignature) bool {
		return colFilter(protoutil.SignedData{
			Data:      signature.Message,
			Signature: signature.Signature,
			Identity:  signature.PeerIdentity,
		})
	})
	if err != nil {
		d.logger.Error("Failed to retrieve peer routing filter for channel", d.chainID, ":", err)
		return nil, err
	}

	m := pvtDataMsg.GetPrivateData().Payload

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the collection name in PutPrivateData matches a collection defined in the chaincode's collection config
  2. If the collection was removed/renamed via collection config update, accept that old data can no longer be disseminated or restore the collection definition
  3. Re-commit a collection config containing the missing collection

Example fix

// before
err := stub.PutPrivateData("oldCollection", key, value)
// after
// use a collection name present in collections_config.json
err := stub.PutPrivateData("collectionMarbles", key, value)
Defensive patterns

Strategy: validation

Validate before calling

func collectionDefined(cfgPkg *peer.CollectionConfigPackage, name string) bool {
  for _, c := range cfgPkg.GetConfig() {
    if sc := c.GetStaticCollectionConfig(); sc != nil && sc.Name == name { return true }
  }
  return false
}

Try / catch

if err != nil && strings.Contains(err.Error(), "no configuration for collection") {
  // re-check collection name vs collections_config.json
}

Prevention

When it happens

Trigger: computeDisseminationPlan calls getCollectionConfig for a collection name that has no matching StaticCollectionConfig entry in the namespace's CollectionConfigPackage.

Common situations: Data written under an older collection name that was renamed or removed in the latest collection config; typo in collection name in chaincode; reconciliation of private data spanning a config update that dropped the collection.

Related errors


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