hyperledger/fabric · error

unsupported policy type %T

Error message

unsupported policy type %T

What it means

After unmarshalling peer.ApplicationPolicy, Evaluate switches on which Type variant is set. If neither SignaturePolicy nor ChannelConfigPolicyReference is populated (unknown/empty oneof variant), it errors with 'unsupported policy type'.

Source

Thrown at core/policy/application.go:161

	}

	return p.EvaluateSignedData(signatureSet)
}

func (a *ApplicationPolicyEvaluator) Evaluate(policyBytes []byte, signatureSet []*protoutil.SignedData) error {
	p := &peer.ApplicationPolicy{}
	err := proto.Unmarshal(policyBytes, p)
	if err != nil {
		return errors.Wrap(err, "failed to unmarshal ApplicationPolicy bytes")
	}

	switch policy := p.Type.(type) {
	case *peer.ApplicationPolicy_SignaturePolicy:
		return a.evaluateSignaturePolicy(policy.SignaturePolicy, signatureSet)
	case *peer.ApplicationPolicy_ChannelConfigPolicyReference:
		return a.evaluateChannelConfigPolicyReference(policy.ChannelConfigPolicyReference, signatureSet)
	default:
		return errors.Errorf("unsupported policy type %T", policy)
	}
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set one of the Type variants when constructing the policy: ApplicationPolicy_SignaturePolicy or ApplicationPolicy_ChannelConfigPolicyReference
  2. Validate the policy has a Type set before submitting/storing it (fail fast at construction time)
  3. Align Fabric versions — a policy from a newer Fabric peer with a new oneof case cannot be evaluated by an older peer
  4. Check that the serialization round-trip preserved the oneof (some generic proto tooling drops it)

Example fix

// before
policy := &peer.ApplicationPolicy{} // Type never set
err := evaluator.Evaluate(mustMarshal(policy), sigData)
// after
policy := &peer.ApplicationPolicy{Type: &peer.ApplicationPolicy_ChannelConfigPolicyReference{
    ChannelConfigPolicyReference: "/Channel/Application/Endorsement"}}
err := evaluator.Evaluate(mustMarshal(policy), sigData)
Defensive patterns

Strategy: type-guard

Validate before calling

func validApplicationPolicy(p *peer.ApplicationPolicy) error {
    switch p.GetType().(type) {
    case *peer.ApplicationPolicy_SignaturePolicy, *peer.ApplicationPolicy_ChannelConfigPolicyReference:
        return nil
    default:
        return errors.New("ApplicationPolicy.Type must be SignaturePolicy or ChannelConfigPolicyReference")
    }
}

Type guard

func hasPolicyType(p *peer.ApplicationPolicy) bool {
    return p.GetType() != nil
}

Try / catch

if err := evaluator.Evaluate(policyBytes, sigData); err != nil {
    var unsupported bool
    if strings.Contains(err.Error(), "unsupported policy type") { unsupported = true }
    if unsupported {
        // rebuild policy with a supported Type or upgrade peer
    }
    return err
}

Prevention

When it happens

Trigger: Evaluating an ApplicationPolicy message with Type nil (empty message) or a oneof variant added in a newer Fabric version that this peer does not understand.

Common situations: Building ApplicationPolicy structs but forgetting to set the Type field, forwarding policies produced by a newer Fabric release to an older peer, or proto decode of an unknown oneof case being dropped.

Related errors


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