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, nilView on GitHub (pinned to 2736b63f8f)
Solutions
- Check the wrapped cause for signing vs marshaling failure
- Confirm the MSP directory contains both keystore/ (private key) and signcerts/ (certificate) for the same identity
- Re-enroll the user identity (fabric-ca-client enroll) if the cert is expired
- 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
- Rotate/re-enroll certificates before expiry
- Ensure keystore and signcerts belong to the same identity
- Fix crypto-material file permissions
- Validate identity with fabric-ca-client getidentity first
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
- could not create a signed Deliver SeekInfo message, somethin
- collection-name: %s -- contains an identity that is not part
- Failed verifying that proposal's creator satisfies local MSP
- failed deserializing identity
- cannot create signed proposal, due to %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9d51d6ecf5d56ecf.
Report an issue: GitHub.