{"record":{"id":"36642b0c67d844d7","repo":"hyperledger/fabric","slug":"instantiation-policy-cannot-be-nil-for-a-signedccd","errorCode":null,"errorMessage":"instantiation policy cannot be nil for a SignedCCDeploymentSpec","messagePattern":"instantiation policy cannot be nil for a SignedCCDeploymentSpec","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/scc/lscc/support.go","lineNumber":56,"sourceCode":"}\n\n// GetChaincodesFromLocalStorage returns an array of all chaincode\n// data that have previously been persisted to local storage\nfunc (s *SupportImpl) GetChaincodesFromLocalStorage() (*pb.ChaincodeQueryResponse, error) {\n\treturn ccprovider.GetInstalledChaincodes()\n}\n\n// GetInstantiationPolicy returns the instantiation policy for the\n// supplied chaincode (or the channel's default if none was specified)\nfunc (s *SupportImpl) GetInstantiationPolicy(channel string, ccpack ccprovider.CCPackage) ([]byte, error) {\n\tvar ip []byte\n\tvar err error\n\t// if ccpack is a SignedCDSPackage, return its IP, otherwise use a default IP\n\tsccpack, isSccpack := ccpack.(*ccprovider.SignedCDSPackage)\n\tif isSccpack {\n\t\tip = sccpack.GetInstantiationPolicy()\n\t\tif ip == nil {\n\t\t\treturn nil, errors.Errorf(\"instantiation policy cannot be nil for a SignedCCDeploymentSpec\")\n\t\t}\n\t} else {\n\t\t// the default instantiation policy allows any of the channel MSP admins\n\t\t// to be able to instantiate\n\t\tmspids := s.GetMSPIDs(channel)\n\n\t\tp := policydsl.SignedByAnyAdmin(mspids)\n\t\tip, err = protoutil.Marshal(p)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"error marshalling default instantiation policy\")\n\t\t}\n\t}\n\treturn ip, nil\n}\n\n// CheckInstantiationPolicy checks whether the supplied signed proposal\n// complies with the supplied instantiation policy\nfunc (s *SupportImpl) CheckInstantiationPolicy(signedProp *pb.SignedProposal, chainName string, instantiationPolicy []byte) error {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/scc/lscc/support.go#L38-L74","documentation":"GetInstantiationPolicy returns this error when the supplied chaincode package is a SignedCDSPackage but its instantiation policy is nil. Every signed chaincode deployment spec must carry an instantiation policy (it controls who can instantiate the chaincode), so a missing policy is treated as a hard error rather than falling back to the default admin policy used for non-SignedCDSPackages.","triggerScenarios":"Calling GetInstantiationPolicy (during LSCC's executeInstantiateOrUpgrade path) with a ccpack that is a *ccprovider.SignedCDSPackage whose GetInstantiationPolicy() yields nil — i.e., a SignedCCDeploymentSpec submitted without an instantiation policy, or a package whose policy failed to parse into the expected format.","commonSituations":"Building a SignedCCDeploymentSpec manually via SDK/CLI and omitting the escc/vscc/instantiationPolicy fields; signing a deployment spec with a corrupted or dropped instantiation policy; Fabric SDK versions that don't populate instantiationPolicy on signed proposals.","solutions":["Provide a valid instantiation policy in the SignedCCDeploymentSpec (e.g., a signedBy policy on the channel's admin MSP) and re-sign the deployment spec.","Re-generate the signed deployment spec with your SDK, ensuring instantiationPolicy is marshaled (not nil/empty) before signing.","If the policy failed to deserialize, rebuild the package with a supported Fabric SDK/CLI version consistent with the peer's protobuf definitions.","Alternatively, use a plain (non-signed) ChaincodeDeploymentSpec path, which falls back to the default channel-admin instantiation policy."],"exampleFix":"// before\nsignedDep := &pb.SignedChaincodeDeploymentSpec{ ChaincodeDeploymentSpec: cds } // no instantiation policy\n// after\nip, _ := cautils.GetInstantiationPolicy(channel, mspID, cds)\nsig, _ := cautils.GetSignature(...) \nsignedDep := &pb.SignedChaincodeDeploymentSpec{ ChaincodeDeploymentSpec: cds, InstantiationPolicy: ip, OwnerEndorsements: sig }","handlingStrategy":"validation","validationCode":"// validate the signed spec before submitting the instantiate proposal\nif signedDep.InstantiationPolicy == nil || len(signedDep.InstantiationPolicy) == 0 {\n    return errors.New(\"SignedCCDeploymentSpec must carry a non-empty instantiation policy\")\n}","typeGuard":"func hasInstantiationPolicy(s *pb.SignedChaincodeDeploymentSpec) bool {\n    return s != nil && len(s.InstantiationPolicy) > 0\n}","tryCatchPattern":"// Go: detect the policy error and instruct the caller to re-sign the spec\nif err := instantiateChaincode(...); err != nil {\n    if strings.Contains(err.Error(), \"instantiation policy cannot be nil\") {\n        return fmt.Errorf(\"rebuild the SignedCCDeploymentSpec with an instantiation policy: %w\", err)\n    }\n    return err\n}","preventionTips":["Always populate InstantiationPolicy when constructing SignedChaincodeDeploymentSpec (SDK helpers can generate a default admin policy).","Validate the signed spec client-side (policy non-nil, signature matches) before sending the proposal.","Keep SDK versions aligned with the peer's Fabric version to avoid dropped policy fields.","Prefer current lifecycle (_lifecycle) which removes signed-spec instantiation policies entirely."],"tags":["hyperledger-fabric","lscc","instantiation-policy","chaincode-deployment"],"backgroundTag":"missing-required-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"}