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
- Set one of the Type variants when constructing the policy: ApplicationPolicy_SignaturePolicy or ApplicationPolicy_ChannelConfigPolicyReference
- Validate the policy has a Type set before submitting/storing it (fail fast at construction time)
- Align Fabric versions — a policy from a newer Fabric peer with a new oneof case cannot be evaluated by an older peer
- 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
- Always set the Type oneof when constructing ApplicationPolicy structs
- Validate policies at creation/persistence time, not only at evaluation time
- Keep peer and SDK/CLI Fabric versions aligned to avoid unknown oneof cases
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
- Empty policy element
- missing policy at path: %s
- ConfigPolicy not found at policy path: %s
- unexpected missing policy %s for item %s
- policy for %s not satisfied
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2cc41a0cd4dc0339.
Report an issue: GitHub.