hyperledger/fabric · error

expected a static collection but got %v instead

Error message

expected a static collection but got %v instead

What it means

Discovery only supports static collections when computing endorsement principals from a collection config. When iterating the collection config package, if a collection entry cannot be cast to a StaticCollectionConfig (e.g. it is a different collection type in the future), discovery refuses to process it rather than guessing principals, returning this error.

Source

Thrown at discovery/endorsement/collection.go:26

import (
	"github.com/hyperledger/fabric-protos-go-apiv2/peer"
	"github.com/hyperledger/fabric/common/policies"
	"github.com/hyperledger/fabric/gossip/api"
	"github.com/pkg/errors"
)

func principalsFromCollectionConfig(ccp *peer.CollectionConfigPackage) (principalSetsByCollectionName, error) {
	principalSetsByCollections := make(principalSetsByCollectionName)
	if ccp == nil {
		return principalSetsByCollections, nil
	}
	for _, colConfig := range ccp.Config {
		staticCol := colConfig.GetStaticCollectionConfig()
		if staticCol == nil {
			// Right now we only support static collections, so if we got something else
			// we should refuse to process further
			return nil, errors.Errorf("expected a static collection but got %v instead", colConfig)
		}
		if staticCol.MemberOrgsPolicy == nil {
			return nil, errors.Errorf("MemberOrgsPolicy of %s is nil", staticCol.Name)
		}
		pol := staticCol.MemberOrgsPolicy.GetSignaturePolicy()
		if pol == nil {
			return nil, errors.Errorf("policy of %s is nil", staticCol.Name)
		}
		var principals policies.PrincipalSet
		// We now extract all principals from the policy
		for _, principal := range pol.Identities {
			principals = append(principals, principal)
		}
		principalSetsByCollections[staticCol.Name] = principals
	}
	return principalSetsByCollections, nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-deploy the chaincode collection configuration using only static collections
  2. Inspect the collection config (peer lifecycle chaincode getcollectionsconfig / inspect config package) and remove non-static entries
  3. Align Fabric versions between the tooling that created the config and the peers running discovery
Defensive patterns

Strategy: validation

Validate before calling

for _, col := range collConfig.Config {
    if col.GetStaticCollectionConfig() == nil {
        return fmt.Errorf("non-static collection %v rejected before discovery", col)
    }
}

Type guard

func isStaticCollection(col *pb.CollectionConfig) bool {
    return col.GetStaticCollectionConfig() != nil
}

Try / catch

principals, err := coll.PrincipalsFromCollectionConfig(ccp)
if err != nil {
    if strings.Contains(err.Error(), "expected a static collection") {
        return nil, fmt.Errorf("collection config for %s has non-static entries; redeploy with static collections", cc)
    }
    return nil, err
}

Prevention

When it happens

Trigger: A chaincode's collection config on the channel contains a non-static collection config entry passed through loadMetadataForChannel and principalsFromCollectionConfig during PeersForEndorsement processing.

Common situations: Future/preview collection types written by newer Fabric tooling read by older discovery code; hand-crafted or corrupted collection configs deployed via chaincode definition; chaincode upgraded with an exotic collection spec.

Related errors


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