hyperledger/fabric · error
received nil proposal response
Error message
received nil proposal response
What it means
In getinstalledpackage.go Get, after ProcessProposal returns without error, the code defensively checks that the returned *pb.ProposalResponse is non-nil. A nil response despite a nil error indicates a misbehaving endorser client/connection layer. This is a defensive invariant check rather than an expected user-facing failure.
Source
Thrown at internal/peer/lifecycle/chaincode/getinstalledpackage.go:135
}
proposal, err := i.createProposal()
if err != nil {
return errors.WithMessage(err, "failed to create proposal")
}
signedProposal, err := signProposal(proposal, i.Signer)
if err != nil {
return errors.WithMessage(err, "failed to create signed proposal")
}
proposalResponse, err := i.EndorserClient.ProcessProposal(context.Background(), signedProposal)
if err != nil {
return errors.WithMessage(err, "failed to endorse proposal")
}
if proposalResponse == nil {
return errors.New("received nil proposal response")
}
if proposalResponse.Response == nil {
return errors.New("received proposal response with nil response")
}
if proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {
return errors.Errorf("proposal failed with status: %d - %s", proposalResponse.Response.Status, proposalResponse.Response.Message)
}
return i.writePackage(proposalResponse)
}
func (i *InstalledPackageGetter) writePackage(proposalResponse *pb.ProposalResponse) error {
result := &lb.GetInstalledChaincodePackageResult{}
err := proto.Unmarshal(proposalResponse.Response.Payload, result)
if err != nil {
return errors.Wrap(err, "failed to unmarshal proposal response's response payload")View on GitHub (pinned to 2736b63f8f)
Solutions
- If in tests, fix the mock to return a valid ProposalResponse
- Inspect interceptors/proxies wrapping the endorser client that may swallow responses
- Retry the command; if persistent, check peer connectivity and client library version
Example fix
// before
mock.On("ProcessProposal").Return(nil, nil)
// after
mock.On("ProcessProposal").Return(&pb.ProposalResponse{Response: &pb.Response{Status: 200, Payload: payload}}, nil) Defensive patterns
Strategy: type-guard
Type guard
func validProposalResponse(pr *pb.ProposalResponse) bool {
return pr != nil
} Try / catch
resp, err := client.ProcessProposal(ctx, sp)
if err != nil {
return errors.WithMessage(err, "failed to endorse proposal")
}
if resp == nil {
return errors.New("received nil proposal response")
} Prevention
- Make test mocks return fully populated ProposalResponse objects
- Avoid interceptors that can drop gRPC responses
- Never return (nil, nil) from client wrapper implementations
When it happens
Trigger: i.EndorserClient.ProcessProposal returns (nil, nil) — abnormal gRPC client behavior, custom/intercepted client implementations, or mocks in tests returning nil responses with nil errors.
Common situations: Custom EndorserClient stubs in tests; exotic transports/interceptors dropping the response; virtually never with the stock gRPC endorser client.
Related errors
- failed sending proposal, due to %s
- Failed sending proposal, got %s
- received nil proposal response
- received proposal response with nil response
- orderer `%s` hung up without sending status
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/47761a7c608a3ad0.
Report an issue: GitHub.