hyperledger/fabric · error

Collections do not match

Error message

Collections do not match

What it means

Thrown by ChaincodeParameters.Equal when the Collections package (private data collection configuration) of the new definition is not proto.Equal to the committed one. Collection configuration is part of the chaincode definition and cannot change without a new sequence.

Source

Thrown at core/chaincode/lifecycle/lifecycle.go:136

	EndorsementInfo *lb.ChaincodeEndorsementInfo
	ValidationInfo  *lb.ChaincodeValidationInfo
	Collections     *pb.CollectionConfigPackage
}

func (cp *ChaincodeParameters) Equal(ocp *ChaincodeParameters) error {
	switch {
	case cp.EndorsementInfo.Version != ocp.EndorsementInfo.Version:
		return errors.Errorf("expected Version '%s' does not match passed Version '%s'", cp.EndorsementInfo.Version, ocp.EndorsementInfo.Version)
	case cp.EndorsementInfo.EndorsementPlugin != ocp.EndorsementInfo.EndorsementPlugin:
		return errors.Errorf("expected EndorsementPlugin '%s' does not match passed EndorsementPlugin '%s'", cp.EndorsementInfo.EndorsementPlugin, ocp.EndorsementInfo.EndorsementPlugin)
	case cp.EndorsementInfo.InitRequired != ocp.EndorsementInfo.InitRequired:
		return errors.Errorf("expected InitRequired '%t' does not match passed InitRequired '%t'", cp.EndorsementInfo.InitRequired, ocp.EndorsementInfo.InitRequired)
	case cp.ValidationInfo.ValidationPlugin != ocp.ValidationInfo.ValidationPlugin:
		return errors.Errorf("expected ValidationPlugin '%s' does not match passed ValidationPlugin '%s'", cp.ValidationInfo.ValidationPlugin, ocp.ValidationInfo.ValidationPlugin)
	case !bytes.Equal(cp.ValidationInfo.ValidationParameter, ocp.ValidationInfo.ValidationParameter):
		return errors.Errorf("expected ValidationParameter '%x' does not match passed ValidationParameter '%x'", cp.ValidationInfo.ValidationParameter, ocp.ValidationInfo.ValidationParameter)
	case !proto.Equal(cp.Collections, ocp.Collections):
		return errors.Errorf("Collections do not match")
	default:
	}
	return nil
}

// ChaincodeDefinition contains the chaincode parameters, as well as the sequence number of the definition.
// Note, it does not embed ChaincodeParameters so as not to complicate the serialization.  It is expected
// that any instance will have no nil fields once initialized.
// WARNING: This structure is serialized/deserialized from the DB, re-ordering or adding fields
// will cause opaque checks to fail.
type ChaincodeDefinition struct {
	Sequence        int64
	EndorsementInfo *lb.ChaincodeEndorsementInfo
	ValidationInfo  *lb.ChaincodeValidationInfo
	Collections     *pb.CollectionConfigPackage
}

type ApprovedChaincodeDefinition struct {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Keep collections identical to the committed definition, or increment the sequence number when intentionally updating collections
  2. Re-approve with the same collections.json on all organizations
  3. Validate the collections JSON before approval (peer lifecycle chaincode approveformyorg --collections-file)

Example fix

// before
collections: {newCollection added}, sequence: 1 // committed had original collections
// after
original collections, sequence: 1 // or sequence: 2 with the new collection
Defensive patterns

Strategy: validation

Validate before calling

committed, err := lifecycle.QueryChaincodeDefinition(chname, ccname, publicState)
if err == nil && !proto.Equal(newDef.Collections, committed.Collections) && newDef.Sequence == committed.Sequence {
    return fmt.Errorf("collections change requires sequence bump")
}

Type guard

func sameCollections(a, b *lifecycle.ChaincodeParameters) bool {
    return a != nil && b != nil && proto.Equal(a.Collections, b.Collections)
}

Try / catch

if err := params.Equal(committedParams); err != nil {
    if strings.Contains(err.Error(), "Collections do not match") {
        // reuse committed collections config or bump sequence
    }
    return err
}

Prevention

When it happens

Trigger: Committing a definition whose CollectionConfigPackage differs (added/removed/modified collections) from the committed definition at the same sequence number.

Common situations: Updating collections.json (adding a private data collection) without incrementing sequence; inconsistent collections config approved by different orgs; field-order/name typos making the proto differ.

Related errors


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