hyperledger/fabric · error

unsupported policy type %T on channel '%s'

Error message

unsupported policy type %T on channel '%s'

What it means

The ApplicationPolicy oneof has a default case reached only if a policy type not handled (SignaturePolicy or ChannelConfigPolicyReference) appears — normally only when a new policy type is added to the protobuf oneof while the running peer predates it. The peer cannot interpret the policy type and throws this error with the Go type name.

Source

Thrown at core/chaincode/lifecycle/metadata_provider.go:104

		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 {
		logger.Debugf("chaincode '%s' on channel '%s' not defined in _lifecycle. requesting metadata from lscc", ccName, channel)
		// fallback to legacy metadata via cclifecycle
		return mp.LegacyMetadataProvider.Metadata(channel, ccName, collections...)
	}

	spe, err := mp.toSignaturePolicyEnvelope(channel, ccInfo.Definition.ValidationInfo.ValidationParameter)
	if err != nil {
		logger.Errorf("could not convert policy for chaincode '%s' on channel '%s', err '%s'", ccName, channel, err)
		return nil
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Upgrade all peers to a Fabric version that supports the policy type in use
  2. Re-define the endorsement policy using a supported type (signature policy or channel config reference)
  3. Avoid copying peer state across incompatible Fabric versions
  4. Check for mixed-version peers in the org during upgrades
Defensive patterns

Strategy: validation

Validate before calling

# Before upgrade, verify no peer runs a version older than the network's
# minimum supported Fabric version that understands the policy types in use.
# On each peer:
peer version | grep -E 'Version'

Try / catch

envBytes, err := mp.toSignaturePolicyEnvelope(channelID, policyBytes)
if err != nil {
  if strings.Contains(err.Error(), "unsupported policy type") {
    // upgrade this peer before retrying
  }
}

Prevention

When it happens

Trigger: Metadata calls toSignaturePolicyEnvelope with an ApplicationPolicy whose Type oneof holds an unknown/newer policy type — e.g. a peer on an older Fabric version receiving state or definitions produced by a newer version introducing a new policy type.

Common situations: Rolling upgrade where newer peers/CLIs write new policy types that older peers cannot parse; custom forks adding policy types; state copied between incompatible Fabric versions.

Related errors


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