hyperledger/fabric · error
cannot specify both "--signature-policy" and "--channel-conf
Error message
cannot specify both "--signature-policy" and "--channel-config-policy"
What it means
createPolicyBytes converts the user-supplied endorsement policy flags into a pb.ApplicationPolicy. Fabric forbids supplying both a signature policy (--signature-policy) and a channel config policy (--channel-config-policy) at once, so it returns this error. The two policy types are mutually exclusive representations of the endorsement policy.
Source
Thrown at internal/peer/lifecycle/chaincode/common.go:81
if err != nil {
return nil, err
}
return &pb.SignedProposal{
ProposalBytes: proposalBytes,
Signature: signature,
}, nil
}
func createPolicyBytes(signaturePolicy, channelConfigPolicy string) ([]byte, error) {
if signaturePolicy == "" && channelConfigPolicy == "" {
// no policy, no problem
return nil, nil
}
if signaturePolicy != "" && channelConfigPolicy != "" {
// mo policies, mo problems
return nil, errors.New("cannot specify both \"--signature-policy\" and \"--channel-config-policy\"")
}
var applicationPolicy *pb.ApplicationPolicy
if signaturePolicy != "" {
signaturePolicyEnvelope, err := policydsl.FromString(signaturePolicy)
if err != nil {
return nil, errors.Errorf("invalid signature policy: %s", signaturePolicy)
}
applicationPolicy = &pb.ApplicationPolicy{
Type: &pb.ApplicationPolicy_SignaturePolicy{
SignaturePolicy: signaturePolicyEnvelope,
},
}
}
if channelConfigPolicy != "" {
applicationPolicy = &pb.ApplicationPolicy{View on GitHub (pinned to 2736b63f8f)
Solutions
- Remove one of the two flags from the command line
- Keep only --signature-policy 'OR(...)' for inline policy expressions
- Use only --channel-config-policy /Channel/Application/Endorsement for channel-defined policies
Example fix
// before
peer lifecycle chaincode approveformyorg --signature-policy "OR('Org1.peer','Org2.peer')" --channel-config-policy /Channel/Application/Endorsement ...
// after
peer lifecycle chaincode approveformyorg --signature-policy "OR('Org1.peer','Org2.peer')" ... Defensive patterns
Strategy: validation
Validate before calling
if sigPolicy != "" && ccPolicy != "" {
return errors.New("pass either --signature-policy or --channel-config-policy, not both")
} Try / catch
if err := approveCmd.Execute(); err != nil {
if strings.Contains(err.Error(), "cannot specify both") {
// strip one of the policy flags and rerun
}
} Prevention
- Keep only one policy flag in scripts/templates
- Sanitize inherited command-line strings before appending policy flags
- Prefer channel config policies in multi-org setups to avoid duplicates
When it happens
Trigger: Approve or Install (via createInput → createPolicyBytes) invoked with both --signature-policy and --channel-config-policy set to non-empty values.
Common situations: Copy-pasting a command line and adding a second policy flag; scripts that append policy flags unconditionally leaving a stale default.
Related errors
- invalid signature policy: %s
- query iterator not found
- application config does not exist for channel '%s'
- unknown chaincode '%s' for channel '%s'
- could not find chaincode with package id '%s'
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a8732afcd3e4755f.
Report an issue: GitHub.