hyperledger/fabric · error

Cannot create signed proposal, due to %s

Error message

Cannot create signed proposal, due to %s

What it means

Returned by getChannels when signing the GetChannels proposal fails. protoutil.GetSignedProposal signs the proposal with the client's signing identity; a failure here is wrapped and returned before any network call.

Source

Thrown at internal/peer/channel/list.go:64

	invocation := &pb.ChaincodeInvocationSpec{
		ChaincodeSpec: &pb.ChaincodeSpec{
			Type:        pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]),
			ChaincodeId: &pb.ChaincodeID{Name: "cscc"},
			Input:       &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.GetChannels)}},
		},
	}

	var prop *pb.Proposal
	c, _ := cc.cf.Signer.Serialize()
	prop, _, err = protoutil.CreateProposalFromCIS(common2.HeaderType_ENDORSER_TRANSACTION, "", invocation, c)
	if err != nil {
		return nil, fmt.Errorf("Cannot create proposal, due to %s", err)
	}

	var signedProp *pb.SignedProposal
	signedProp, err = protoutil.GetSignedProposal(prop, cc.cf.Signer)
	if err != nil {
		return nil, fmt.Errorf("Cannot create signed proposal, due to %s", err)
	}

	proposalResp, err := cc.cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
	if err != nil {
		return nil, fmt.Errorf("Failed sending proposal, got %s", err)
	}

	if proposalResp.Response == nil || proposalResp.Response.Status != http.StatusOK {
		return nil, fmt.Errorf("Received bad response, status %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)
	}

	var channelQueryResponse pb.ChannelQueryResponse
	err = proto.Unmarshal(proposalResp.Response.Payload, &channelQueryResponse)
	if err != nil {
		return nil, fmt.Errorf("Cannot read channels list response, %s", err)
	}

	return channelQueryResponse.Channels, nil

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the wrapped cause for signing vs marshaling failure
  2. Confirm the MSP directory contains both keystore/ (private key) and signcerts/ (certificate) for the same identity
  3. Re-enroll the user identity (fabric-ca-client enroll) if the cert is expired
  4. Correct file ownership/permissions so the CLI can read the key

Example fix

// before: keystore permissions block reading key -> signing fails
// ls -l msp/keystore  -> 0000 priv_sk
// after
chmod 600 msp/keystore/priv_sk && peer channel list -c mychannel
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: cert+key pair must exist
for _, p := range []string{filepath.Join(mspDir, "keystore"), filepath.Join(mspDir, "signcerts")} {
    if n, _ := os.ReadDir(p); len(n) == 0 { return fmt.Errorf("missing material in %s", p) }
}

Try / catch

signedProp, err := protoutil.GetSignedProposal(prop, cc.cf.Signer)
if err != nil {
    return nil, fmt.Errorf("Cannot create signed proposal, due to %s", err)
}

Prevention

When it happens

Trigger: protoutil.GetSignedProposal(prop, cc.cf.Signer) errors — the private key is missing/unreadable, or the signing identity is invalid so the proposal cannot be signed and marshaled.

Common situations: MSP keystore empty or unreadable; expired enrollment certificate; wrong MSP path passed to the CLI; crypto material generated for a different organization.

Related errors


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