hyperledger/fabric · error
policy with reference '%s' on channel '%s' is not convertibl
Error message
policy with reference '%s' on channel '%s' is not convertible to SignaturePolicyEnvelope
What it means
When the ApplicationPolicy holds a ChannelConfigPolicyReference, lifecycle resolves it to a policies.Policy and then type-asserts to policies.Converter so it can be converted to a SignaturePolicyEnvelope. Policies that are not convertible (e.g. an ImplicitMetaPolicy) fail the assertion and this error is thrown. Discovery needs a concrete signature policy but only an abstract reference was found.
Source
Thrown at core/chaincode/lifecycle/metadata_provider.go:93
func (mp *MetadataProvider) toSignaturePolicyEnvelope(channelID string, policyBytes []byte) ([]byte, error) {
p := &peer.ApplicationPolicy{}
err := proto.Unmarshal(policyBytes, p)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal ApplicationPolicy bytes")
}
switch policy := p.Type.(type) {
case *peer.ApplicationPolicy_SignaturePolicy:
return protoutil.MarshalOrPanic(policy.SignaturePolicy), nil
case *peer.ApplicationPolicy_ChannelConfigPolicyReference:
p, err := mp.ChannelPolicyReferenceProvider.NewPolicy(channelID, policy.ChannelConfigPolicyReference)
if err != nil {
return nil, errors.WithMessagef(err, "could not retrieve policy for reference '%s' on channel '%s'", policy.ChannelConfigPolicyReference, channelID)
}
cp, ok := p.(policies.Converter)
if !ok {
return nil, errors.Errorf("policy with reference '%s' on channel '%s' is not convertible to SignaturePolicyEnvelope", policy.ChannelConfigPolicyReference, channelID)
}
spe, err := cp.Convert()
if err != nil {
return nil, errors.WithMessagef(err, "error converting policy with reference '%s' on channel '%s' to SignaturePolicyEnvelope", policy.ChannelConfigPolicyReference, channelID)
}
return proto.Marshal(spe)
default:
// this will only happen if a new policy type is added to the oneof
return nil, errors.Errorf("unsupported policy type %T on channel '%s'", policy, channelID)
}
}
// Metadata implements the metadata retriever support interface for service discovery
func (mp *MetadataProvider) Metadata(channel string, ccName string, collections ...string) *chaincode.Metadata {
ccInfo, err := mp.ChaincodeInfoProvider.ChaincodeInfo(channel, ccName)
if err != nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Set the chaincode endorsement policy to an explicit signature policy (e.g. -E "AND('Org1.peer','Org2.peer')") instead of an implicit-meta channel reference
- Define a signature-policy in channel config and reference that instead of the implicit-meta one
- If implicit meta semantics are needed, use discovery's layout computation with a convertible policy
- Document that discovery of this chaincode requires a SignaturePolicyEnvelope-representable policy
Example fix
// before: implicit-meta reference
-E /Channel/Application/Endorsement
// error: not convertible to SignaturePolicyEnvelope
// after: explicit signature policy
peer lifecycle chaincode approveformyorg -C mychannel --name mycc --sequence 1 -E "AND('Org1MSP.peer','Org2MSP.peer')" Defensive patterns
Strategy: validation
Validate before calling
# Before setting an endorsement policy reference, ensure it is a signature policy, # not an implicit-meta policy: jq '.channel_group.groups.Application.policies["MyPolicy"].policy.type' config.json # 1 = SignaturePolicy (ok), 3 = ImplicitMeta (will hit 'not convertible')
Try / catch
envBytes, err := mp.toSignaturePolicyEnvelope(channelID, policyBytes)
if err != nil {
if strings.Contains(err.Error(), "not convertible to SignaturePolicyEnvelope") {
// request an explicit signature policy instead of the channel reference
}
} Prevention
- Use AND/OR signature policies for endorsement when discovery metadata is needed
- Avoid referencing implicit-meta policies as endorsement policies
- Document policy types in channel config
- Test discovery output after approval
When it happens
Trigger: Metadata (service discovery) is asked for a chaincode whose endorsement policy is a channel-config reference to a policy type lacking a Convert() implementation, such as an implicit-meta policy.
Common situations: Setting endorsement policy to '/Channel/Application/Endorsement' (implicit meta) where discovery requires a signature policy; using Any/Majority implicit policies as endorsement policy references; legacy discovery clients expecting envelope-form policies.
Related errors
- error converting policy with reference '%s' on channel '%s'
- policy manager for channel %s doesn't exist
- failed obtaining channel application writers policy
- invalid signature policy: %s
- identity index out of range, requested %v, but identities le
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/1c9918c76227e6af.
Report an issue: GitHub.