hyperledger/fabric · error
subpolicy number %d type %T of policy %s is not convertible
Error message
subpolicy number %d type %T of policy %s is not convertible
What it means
ImplicitMetaPolicy.Convert walks its subpolicies and requires each one to implement the Converter interface. If a subpolicy is of a type that cannot be converted (e.g. a raw SignaturePolicy or an unimplemented policy type), conversion aborts with this error naming the index, dynamic type, and policy name.
Source
Thrown at common/policies/convert.go:117
converted := &cb.SignaturePolicyEnvelope{
Version: 0,
Rule: &cb.SignaturePolicy{
Type: &cb.SignaturePolicy_NOutOf_{
NOutOf: &cb.SignaturePolicy_NOutOf{
N: int32(p.Threshold),
},
},
},
}
// the conversion approach for an implicit meta
// policy is to convert each of the subpolicies,
// merge it with the previous one and return the
// merged policy
for i, subPolicy := range p.SubPolicies {
convertibleSubpolicy, ok := subPolicy.(Converter)
if !ok {
return nil, errors.Errorf("subpolicy number %d type %T of policy %s is not convertible", i, subPolicy, p.SubPolicyName)
}
spe, err := convertibleSubpolicy.Convert()
if err != nil {
return nil, errors.WithMessagef(err, "failed to convert subpolicy number %d of policy %s", i, p.SubPolicyName)
}
merge(converted, spe)
}
return converted, nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the channel configuration so each subpolicy of the implicit meta policy is itself an ImplicitMetaPolicy (convertible)
- Inspect the %T in the error to identify the offending subpolicy type and correct its configtx entry
- Validate the channel config (configtxgen / configtxlator) before submitting the update
- If receiving this from a peer, reject/fix the offending channel creation or update transaction
Example fix
# before (configtx.yaml)
Policy: OR("Admins") # becomes a signature policy subpolicy
# after
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers" # nested implicit-meta subpolicies only Defensive patterns
Strategy: validation
Validate before calling
func subPoliciesConvertible(cfg *cb.ConfigGroup) error {
for name, p := range cfg.Policies {
imp := &cb.ImplicitMetaPolicy{}
if err := proto.Unmarshal(p.Policy.Value, imp); err == nil {
for _, sp := range imp.SubPolicies {
if _, ok := sp.(policies.Converter); !ok {
return fmt.Errorf("subpolicy %s of %s is not convertible (%T)", name, name, sp)
}
}
}
}
return nil
} Type guard
func isConvertibleSubpolicy(sp interface{}) bool {
_, ok := sp.(policies.Converter)
return ok
} Try / catch
converted, err := impPolicy.Convert()
if err != nil {
if strings.Contains(err.Error(), "is not convertible") {
log.Errorf("fix channel config: %v", err) // correct the offending subpolicy type in configtx
}
return err
} Prevention
- Author nested policies in configtx.yaml only as ImplicitMeta rules
- Run configtxgen/configtxlator validation before submitting channel updates
- Check the %T in the error to identify the offending subpolicy type
- Reject malformed channel creation/update transactions at submission time
When it happens
Trigger: Calling Convert() on an ImplicitMetaPolicy whose config proto contains subpolicies that are not convertible — e.g. a channel config policy built with a SignaturePolicyEnvelope instead of another ImplicitMetaPolicy, or an unknown policy type injected via malformed channel creation/update config.
Common situations: Mis-authored configtx.yaml where a nested policy is a signature policy rather than an implicit meta policy; malformed channel update transactions; proto payloads deserialized into unexpected types; tests like TestImplicitMetaPolicy_Convert* exercising bad subpolicy types.
Related errors
- chaincode type not supported: %s
- failed to copy metadataDir directory folder: %s
- error unmarshalling YAML file %s: %s
- no endpoints
- Error unmarshalling to ImplicitMetaPolicy: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2d70e255dc6a069e.
Report an issue: GitHub.