hyperledger/fabric · error
received proposal response with nil response
Error message
received proposal response with nil response
What it means
Even when the ProposalResponse wrapper is non-nil, its embedded Response payload must be present for Commit to inspect the status. A nil Response is treated as a malformed endorser reply and rejected.
Source
Thrown at internal/peer/lifecycle/chaincode/commit.go:196
}
responses = append(responses, proposalResponse)
}
if len(responses) == 0 {
// this should only be empty due to a programming bug
return errors.New("no proposal responses received")
}
// all responses will be checked when the signed transaction is created.
// for now, just set this so we check the first response's status
proposalResponse := responses[0]
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)
}
// assemble a signed transaction (it's an Envelope message)
env, err := protoutil.CreateSignedTx(proposal, c.Signer, responses...)
if err != nil {
return errors.WithMessage(err, "failed to create signed transaction")
}
var dg *chaincode.DeliverGroup
var ctx context.Context
if c.Input.WaitForEvent {
var cancelFunc context.CancelFunc
ctx, cancelFunc = context.WithTimeout(context.Background(), c.Input.WaitForEventTimeout)
defer cancelFunc()
View on GitHub (pinned to 2736b63f8f)
Solutions
- Check the endorser's returned ProposalResponse for a non-nil Response field before appending.
- Verify protobuf serialization/deserialization of responses in custom clients.
- Use the fabric protoutil helpers to construct responses correctly.
- Re-run the transaction against healthy endorsers.
Example fix
// before
responses = append(responses, resp)
// after
if resp == nil || resp.Response == nil { return errors.New("malformed proposal response") }
responses = append(responses, resp) Defensive patterns
Strategy: type-guard
Validate before calling
for _, resp := range responses {
if resp == nil || resp.Response == nil {
return errors.New("malformed proposal response: nil Response")
}
} Type guard
func hasResponsePayload(r *pb.ProposalResponse) bool { return r != nil && r.Response != nil } Try / catch
if err := commit(...); err != nil {
if strings.Contains(err.Error(), "nil response") {
// re-endorse; inspect protobuf deserialization in custom clients
}
} Prevention
- Validate the full ProposalResponse structure, not just the pointer.
- Use fabric protoutil/protobuf helpers for serializing responses.
- Re-endorse from healthy peers when responses are malformed.
When it happens
Trigger: responses[0].Response is nil when Commit examines the first proposal response — a structurally malformed response from an endorser.
Common situations: Corrupted or hand-crafted proposal responses in custom tooling; proto deserialization producing a non-nil wrapper with nil payload; buggy mock endorsers in tests.
Related errors
- received nil proposal response
- block must be different from nil, channel=%s
- Invalid signed proposal during check policy on channel [%s]
- proto: Marshal called with nil
- chaincode interest is nil
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9b20cff5320d83fd.
Report an issue: GitHub.