hyperledger/fabric · error

policy of %s is nil

Error message

policy of %s is nil

What it means

After confirming MemberOrgsPolicy exists, discovery extracts principals from its signature policy. If the policy is present but is not a signature policy (GetSignaturePolicy returns nil), discovery cannot enumerate the endorsing organizations and returns this error for the named collection.

Source

Thrown at discovery/endorsement/collection.go:33

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
}

type principalSetsByCollectionName map[string]policies.PrincipalSet

// toIdentityFilter converts this principalSetsByCollectionName mapping to a filter
// which accepts or rejects identities of peers.
func (psbc principalSetsByCollectionName) toIdentityFilter(channel string, evaluator principalEvaluator, cc *peer.ChaincodeCall) (identityFilter, error) {
	var principalSets policies.PrincipalSets
	for _, col := range cc.CollectionNames {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure memberOrgsPolicy.signaturePolicy with a valid identities array exists in the collection config
  2. Redeploy/upgrade the chaincode definition with a corrected collections file
  3. Validate collection JSON against the Fabric schema before chaincode approval

Example fix

// before
"memberOrgsPolicy": {}

// after
"memberOrgsPolicy": {"signaturePolicy": {"identities": [{"role": {"name": "peer", "mspId": "Org1MSP"}}]}}
Defensive patterns

Strategy: validation

Validate before calling

for _, col := range collConfig.Config {
    sc := col.GetStaticCollectionConfig()
    if sc != nil && sc.GetMemberOrgsPolicy() != nil && sc.GetMemberOrgsPolicy().GetSignaturePolicy() == nil {
        return fmt.Errorf("collection %s memberOrgsPolicy has no signature policy", sc.Name)
    }
}

Type guard

func hasSignaturePolicy(sc *pb.StaticCollectionConfig) bool {
    return sc != nil && sc.GetMemberOrgsPolicy() != nil && sc.GetMemberOrgsPolicy().GetSignaturePolicy() != nil
}

Try / catch

_, err := coll.PrincipalsFromCollectionConfig(ccp)
if err != nil {
    if strings.Contains(err.Error(), "policy of") {
        return nil, fmt.Errorf("collection memberOrgsPolicy must be a signature policy: %v", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: A collection whose MemberOrgsPolicy uses a non-signature policy type (or is an empty wrapper) is processed during PeersForEndorsement principal computation.

Common situations: Collection configs generated by tooling that emits an empty memberOrgsPolicy object; manually edited collection JSON where the signaturePolicy body was removed; version skew between config producers and discovery service.

Related errors


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