hyperledger/fabric · error

collection config access policy is nil

Error message

collection config access policy is nil

What it means

getPolicy requires the CollectionPolicyConfig to carry a signature-policy envelope. This error fires when GetSignaturePolicy returns nil — the policy config exists but has no signature policy payload, so an EnvelopeBasedPolicy cannot be constructed from it.

Source

Thrown at core/common/privdata/util.go:28

	mspp "github.com/hyperledger/fabric-protos-go-apiv2/msp"
	"github.com/hyperledger/fabric-protos-go-apiv2/peer"
	"github.com/hyperledger/fabric/common/cauthdsl"
	"github.com/hyperledger/fabric/common/policies"
	"github.com/hyperledger/fabric/msp"
	"github.com/pkg/errors"
	"google.golang.org/protobuf/proto"
)

// getPolicy creates a new policy from the policy envelope. It will return an error if the envelope has invalid policy config.
// Some caller (e.g., MembershipProvider.AsMemberOf) may drop the error and treat it as a RejectAll policy.
// In the future, we must revisit the callers if this method will return different types of errors.
func getPolicy(collectionPolicyConfig *peer.CollectionPolicyConfig, deserializer msp.IdentityDeserializer) (policies.Policy, error) {
	if collectionPolicyConfig == nil {
		return nil, errors.New("collection policy config is nil")
	}
	accessPolicyEnvelope := collectionPolicyConfig.GetSignaturePolicy()
	if accessPolicyEnvelope == nil {
		return nil, errors.New("collection config access policy is nil")
	}
	// create access policy from the envelope

	pp := cauthdsl.EnvelopeBasedPolicyProvider{Deserializer: deserializer}
	accessPolicy, err := pp.NewPolicy(accessPolicyEnvelope)
	if err != nil {
		return nil, errors.WithMessage(err, "failed constructing policy object out of collection policy config")
	}

	return accessPolicy, nil
}

// getMemberOrgs returns a map containing member orgs from a list of MSPPrincipals,
// it will skip identities it fails to process
func getMemberOrgs(identities []*mspp.MSPPrincipal, deserializer msp.IdentityDeserializer) map[string]struct{} {
	memberOrgs := map[string]struct{}{}

	// get member org MSP IDs from the envelope

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Populate memberOrgsPolicy.signaturePolicy with a valid cauthdsl signature policy envelope
  2. Regenerate the collections config with a policy tool (e.g., policyexpr / peer CLI templates) and re-approve the chaincode definition
  3. In code, verify accessPolicyEnvelope is non-nil before calling getPolicy

Example fix

// before
cfg := &peer.CollectionPolicyConfig{} // no signature policy -> nil envelope
getPolicy(cfg, deserializer)

// after
cfg := &peer.CollectionPolicyConfig{
  Payload: &peer.CollectionPolicyConfig_SignaturePolicy{
    SignaturePolicy: cauthdsl.SignedByMspMember("Org1MSP"),
  },
}
getPolicy(cfg, deserializer)
Defensive patterns

Strategy: validation

Validate before calling

if cfg == nil || cfg.GetSignaturePolicy() == nil {
  return errors.New("collection policy config lacks a signature policy envelope")
}

Type guard

func hasSignaturePolicy(c *peer.CollectionPolicyConfig) bool {
  return c != nil && c.GetSignaturePolicy() != nil
}

Try / catch

policy, err := getPolicy(cfg, deserializer)
if err != nil {
  if strings.Contains(err.Error(), "access policy is nil") {
    return nil, fmt.Errorf("regenerate collections config with a signaturePolicy: %w", err)
  }
  return nil, err
}

Prevention

When it happens

Trigger: A CollectionPolicyConfig with an empty or non-signature payload (e.g., zero-value struct) passed to getPolicy from setupAccessPolicy or tests (TestGetPolicyFailed).

Common situations: Programmatically built collection policies missing the SignaturePolicy field, config authoring tools that emit memberOrgsPolicy shells without the envelope, format upgrades that dropped the signature policy.

Related errors


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