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

  1. 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
  2. Define a signature-policy in channel config and reference that instead of the implicit-meta one
  3. If implicit meta semantics are needed, use discovery's layout computation with a convertible policy
  4. 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

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


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