{"record":{"id":"9ac7a9c9672e46b5","repo":"hyperledger/fabric","slug":"collection-config-access-policy-is-nil-9ac7a9","errorCode":null,"errorMessage":"collection config access policy is nil","messagePattern":"collection config access policy is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/common/privdata/util.go","lineNumber":28,"sourceCode":"\tmspp \"github.com/hyperledger/fabric-protos-go-apiv2/msp\"\n\t\"github.com/hyperledger/fabric-protos-go-apiv2/peer\"\n\t\"github.com/hyperledger/fabric/common/cauthdsl\"\n\t\"github.com/hyperledger/fabric/common/policies\"\n\t\"github.com/hyperledger/fabric/msp\"\n\t\"github.com/pkg/errors\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// getPolicy creates a new policy from the policy envelope. It will return an error if the envelope has invalid policy config.\n// Some caller (e.g., MembershipProvider.AsMemberOf) may drop the error and treat it as a RejectAll policy.\n// In the future, we must revisit the callers if this method will return different types of errors.\nfunc getPolicy(collectionPolicyConfig *peer.CollectionPolicyConfig, deserializer msp.IdentityDeserializer) (policies.Policy, error) {\n\tif collectionPolicyConfig == nil {\n\t\treturn nil, errors.New(\"collection policy config is nil\")\n\t}\n\taccessPolicyEnvelope := collectionPolicyConfig.GetSignaturePolicy()\n\tif accessPolicyEnvelope == nil {\n\t\treturn nil, errors.New(\"collection config access policy is nil\")\n\t}\n\t// create access policy from the envelope\n\n\tpp := cauthdsl.EnvelopeBasedPolicyProvider{Deserializer: deserializer}\n\taccessPolicy, err := pp.NewPolicy(accessPolicyEnvelope)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"failed constructing policy object out of collection policy config\")\n\t}\n\n\treturn accessPolicy, nil\n}\n\n// getMemberOrgs returns a map containing member orgs from a list of MSPPrincipals,\n// it will skip identities it fails to process\nfunc getMemberOrgs(identities []*mspp.MSPPrincipal, deserializer msp.IdentityDeserializer) map[string]struct{} {\n\tmemberOrgs := map[string]struct{}{}\n\n\t// get member org MSP IDs from the envelope","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/common/privdata/util.go#L10-L46","documentation":"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.","triggerScenarios":"A CollectionPolicyConfig with an empty or non-signature payload (e.g., zero-value struct) passed to getPolicy from setupAccessPolicy or tests (TestGetPolicyFailed).","commonSituations":"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.","solutions":["Populate memberOrgsPolicy.signaturePolicy with a valid cauthdsl signature policy envelope","Regenerate the collections config with a policy tool (e.g., policyexpr / peer CLI templates) and re-approve the chaincode definition","In code, verify accessPolicyEnvelope is non-nil before calling getPolicy"],"exampleFix":"// before\ncfg := &peer.CollectionPolicyConfig{} // no signature policy -> nil envelope\ngetPolicy(cfg, deserializer)\n\n// after\ncfg := &peer.CollectionPolicyConfig{\n  Payload: &peer.CollectionPolicyConfig_SignaturePolicy{\n    SignaturePolicy: cauthdsl.SignedByMspMember(\"Org1MSP\"),\n  },\n}\ngetPolicy(cfg, deserializer)","handlingStrategy":"validation","validationCode":"if cfg == nil || cfg.GetSignaturePolicy() == nil {\n  return errors.New(\"collection policy config lacks a signature policy envelope\")\n}","typeGuard":"func hasSignaturePolicy(c *peer.CollectionPolicyConfig) bool {\n  return c != nil && c.GetSignaturePolicy() != nil\n}","tryCatchPattern":"policy, err := getPolicy(cfg, deserializer)\nif err != nil {\n  if strings.Contains(err.Error(), \"access policy is nil\") {\n    return nil, fmt.Errorf(\"regenerate collections config with a signaturePolicy: %w\", err)\n  }\n  return nil, err\n}","preventionTips":["Always populate SignaturePolicy via cauthdsl constructors","Run peer CLI collection config validation before approval","Add tests exercising getPolicy on every shipped collection config"],"tags":["privdata","nil-check","policy"],"backgroundTag":"missing-collection-policy","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}