hyperledger/fabric · error
policy (name='%s',type='%T') is not convertible to Signature
Error message
policy (name='%s',type='%T') is not convertible to SignaturePolicyEnvelope
What it means
PolicyLogger.Convert converts a policy back into a SignaturePolicyEnvelope for signature collection (e.g. building config signatures). If the wrapped policy does not implement the Converter interface, conversion is impossible and this error names the policy and its concrete Go type.
Source
Thrown at common/policies/policy.go:316
defer logger.Debugf("== Done Evaluating %T Policy %s", pl.Policy, pl.policyName)
}
err := pl.Policy.EvaluateIdentities(identities)
if err != nil {
logger.Debugf("Signature set did not satisfy policy %s", pl.policyName)
} else {
logger.Debugf("Signature set satisfies policy %s", pl.policyName)
}
return err
}
func (pl *PolicyLogger) Convert() (*cb.SignaturePolicyEnvelope, error) {
logger.Debugf("== Converting %T Policy %s ==", pl.Policy, pl.policyName)
convertiblePolicy, ok := pl.Policy.(Converter)
if !ok {
logger.Errorf("policy (name='%s',type='%T') is not convertible to SignaturePolicyEnvelope", pl.policyName, pl.Policy)
return nil, errors.Errorf("policy (name='%s',type='%T') is not convertible to SignaturePolicyEnvelope", pl.policyName, pl.Policy)
}
cp, err := convertiblePolicy.Convert()
if err != nil {
logger.Errorf("== Error Converting %T Policy %s, err %s", pl.Policy, pl.policyName, err.Error())
} else {
logger.Debugf("== Done Converting %T Policy %s", pl.Policy, pl.policyName)
}
return cp, err
}
// GetPolicy returns a policy and true if it was the policy requested, or false if it is the default reject policy
func (pm *ManagerImpl) GetPolicy(id string) (Policy, bool) {
if id == "" {
logger.Errorf("Returning dummy reject all policy because no policy ID supplied")
return rejectPolicy(id), false
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Only call Convert on policies known to implement Converter (signature-type policies built from a SignaturePolicyEnvelope)
- Check policy existence first so rejectPolicy is never converted
- Implement Convert() on custom policy types if conversion must be supported
Example fix
// before
p, _ := mgr.GetPolicy("Missing")
env, err := p.(*policies.PolicyLogger).Convert() // not convertible
// after
if c, ok := p.(policies.Converter); ok {
env, err := c.Convert()
} Defensive patterns
Strategy: type-guard
Validate before calling
// Verify the policy exists and is a signature policy before converting
if _, ok := mgr.Manager(nil); !ok { return errors.New("no manager") }
p, _ := mgr.GetPolicy(name)
_ = p Type guard
func asConverter(p policies.Policy) (policies.Converter, bool) {
c, ok := p.(policies.Converter)
return c, ok
} Try / catch
env, err := policyLogger.Convert()
if err != nil && strings.Contains(err.Error(), "is not convertible") {
return fmt.Errorf("cannot sign against policy %s: not a signature policy", name)
} Prevention
- Only convert policies you know were built from SignaturePolicyEnvelopes
- Guard with a Converter interface assertion before calling Convert
- Avoid converting rejectPolicy placeholders returned for missing names
When it happens
Trigger: Calling Convert on a PolicyLogger whose underlying Policy is not convertible (e.g. a rejectPolicy placeholder from GetPolicy on a missing name, or a custom policy type without a Convert method).
Common situations: Attempting to pre-sign a config update using a policy that resolved to the reject sentinel; custom policy implementations that do not implement Converter; invoking conversion on implicit policies whose sub-policies are unconvertible.
Related errors
- consenter options type mismatch
- wrong chain type
- malformed org definition for org: %s
- organization %s not found
- error encode input
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/d878c9a3aaaa402b.
Report an issue: GitHub.