{"record":{"id":"f90e60c8ef6d5cd1","repo":"hyperledger/fabric","slug":"error-converting-policy-with-reference-s-on-cha","errorCode":null,"errorMessage":"error converting policy with reference '%s' on channel '%s' to SignaturePolicyEnvelope","messagePattern":"error converting policy with reference '(.+?)' on channel '(.+?)' to SignaturePolicyEnvelope","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/metadata_provider.go","lineNumber":98,"sourceCode":"\t}\n\n\tswitch policy := p.Type.(type) {\n\tcase *peer.ApplicationPolicy_SignaturePolicy:\n\t\treturn protoutil.MarshalOrPanic(policy.SignaturePolicy), nil\n\tcase *peer.ApplicationPolicy_ChannelConfigPolicyReference:\n\t\tp, err := mp.ChannelPolicyReferenceProvider.NewPolicy(channelID, policy.ChannelConfigPolicyReference)\n\t\tif err != nil {\n\t\t\treturn nil, errors.WithMessagef(err, \"could not retrieve policy for reference '%s' on channel '%s'\", policy.ChannelConfigPolicyReference, channelID)\n\t\t}\n\n\t\tcp, ok := p.(policies.Converter)\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"policy with reference '%s' on channel '%s' is not convertible to SignaturePolicyEnvelope\", policy.ChannelConfigPolicyReference, channelID)\n\t\t}\n\n\t\tspe, err := cp.Convert()\n\t\tif err != nil {\n\t\t\treturn nil, errors.WithMessagef(err, \"error converting policy with reference '%s' on channel '%s' to SignaturePolicyEnvelope\", policy.ChannelConfigPolicyReference, channelID)\n\t\t}\n\n\t\treturn proto.Marshal(spe)\n\tdefault:\n\t\t// this will only happen if a new policy type is added to the oneof\n\t\treturn nil, errors.Errorf(\"unsupported policy type %T on channel '%s'\", policy, channelID)\n\t}\n}\n\n// Metadata implements the metadata retriever support interface for service discovery\nfunc (mp *MetadataProvider) Metadata(channel string, ccName string, collections ...string) *chaincode.Metadata {\n\tccInfo, err := mp.ChaincodeInfoProvider.ChaincodeInfo(channel, ccName)\n\tif err != nil {\n\t\tlogger.Debugf(\"chaincode '%s' on channel '%s' not defined in _lifecycle. requesting metadata from lscc\", ccName, channel)\n\t\t// fallback to legacy metadata via cclifecycle\n\t\treturn mp.LegacyMetadataProvider.Metadata(channel, ccName, collections...)\n\t}\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/metadata_provider.go#L80-L116","documentation":"After asserting the resolved policy implements policies.Converter, lifecycle calls cp.Convert() to produce a SignaturePolicyEnvelope. If that conversion fails — the policy cannot be materialized as a signature policy envelope, typically because referenced principals/MSPs cannot be resolved — this wrapped error is thrown. The underlying cause is embedded in the message.","triggerScenarios":"Metadata (service discovery) resolves a ChannelConfigPolicyReference to a converter policy whose Convert() returns an error, e.g. the policy references an MSP not configured on the peer or the channel config is stale/malformed.","commonSituations":"MSPs referenced by the policy missing from the peer's MSP config; partially applied channel config updates; config block fetched before an update completed; principals in the policy no longer exist after org changes.","solutions":["Read the wrapped cause in the error message and fix the underlying policy definition in channel config","Verify all MSPs referenced by the policy are configured on the peer (peer's msp config directory)","Refetch the latest channel config block after updates; ensure the peer is on the current config sequence","Redefine the endorsement policy as a simple explicit signature policy"],"exampleFix":"# before: policy references an org whose MSP is not deployed on the peer\n# error converting policy with reference 'myPolicy' ...\n# after: deploy the missing org MSP to the peer, then re-test discovery\npeer channel fetch config config.block -c mychannel\nconfigtxlator proto_decode --input config.block --type common.Config > config.json\n# verify the referenced org exists, then restart peer with updated msp directory","handlingStrategy":"try-catch","validationCode":"# Ensure all MSPs referenced by the policy exist on the peer\nls peer/msp/  # and compare against principals in the policy definition via configtxlator","typeGuard":null,"tryCatchPattern":"envBytes, err := mp.toSignaturePolicyEnvelope(channelID, policyBytes)\nif err != nil {\n  if strings.Contains(err.Error(), \"error converting policy with reference\") {\n    // inspect wrapped cause; likely MSP/config problem — fix channel config\n  }\n}","preventionTips":["Keep peer MSP configuration in sync with channel config principals","Apply config updates atomically across the network","Refetch config blocks after updates","Prefer simple signature policies over complex references"],"tags":["fabric","policy","discovery","conversion","msp"],"backgroundTag":"policy-not-convertible","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"}