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

  1. Remove one of the two flags from the command line
  2. Keep only --signature-policy 'OR(...)' for inline policy expressions
  3. 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

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


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