hyperledger/fabric · error

received proposal response with nil response

Error message

received proposal response with nil response

What it means

This error is returned by ReadinessCheck when the endorser returned a proposalResponse whose inner Response field is nil. The gateway-level protobuf message arrived, but the payload carrying status/message was not populated, so the library cannot evaluate success and refuses to dereference nil. This usually signals a malformed or truncated response from the peer.

Source

Thrown at internal/peer/lifecycle/chaincode/checkcommitreadiness.go:182

	}

	signedProposal, err := signProposal(proposal, c.Signer)
	if err != nil {
		return errors.WithMessage(err, "failed to create signed proposal")
	}

	// checkcommitreadiness currently only supports a single peer
	proposalResponse, err := c.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("query failed with status: %d - %s", proposalResponse.Response.Status, proposalResponse.Response.Message)
	}

	if strings.ToLower(c.Input.OutputFormat) == "json" {
		// Unmarshal the proposal response to add descriptions to mismatch items
		readinessResult := &lb.CheckCommitReadinessResult{}
		err := proto.Unmarshal(proposalResponse.Response.Payload, readinessResult)
		if err != nil {
			return errors.Wrap(err, "failed to unmarshal readiness result")
		}

		if c.Input.InspectionEnabled {
			for org, mismatches := range readinessResult.Mismatches {
				for i, item := range mismatches.Items {
					mismatches.Items[i] = c.mismatchItemWithDescription(item)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Retry against the peer; if it persists, inspect peer logs for endorsement failures and verify peer/fabric-cli version compatibility
  2. Remove or fix any proxy/middleware between the client and the peer that could alter the response payload
  3. If mocking EndorserClient in tests, populate the Response field: &peer.ProposalResponse{Response: &peer.Response{Status: 200}}

Example fix

// before (test mock)
return &peer.ProposalResponse{}, nil // nil Response -> error
// after
return &peer.ProposalResponse{Response: &peer.Response{Status: 200, Payload: approvalBytes}}, nil
Defensive patterns

Strategy: type-guard

Validate before calling

if resp != nil && resp.Response == nil {
    return errors.New("endorser returned an empty proposal response payload")
}

Type guard

func hasInnerResponse(r *pb.ProposalResponse) bool {
    return r != nil && r.Response != nil
}

Try / catch

if resp.Response == nil {
    return errors.New("received proposal response with nil response")
}
// check resp.Response.Status == int32(cb.Status_SUCCESS) before reading the payload

Prevention

When it happens

Trigger: EndorserClient.ProcessProposal returns a non-nil proposalResponse with Response == nil — e.g. a buggy/misbehaving peer or proxy, or a stubbed client in tests returning a bare &peer.ProposalResponse{}.

Common situations: Custom service meshes/proxies in front of the peer stripping payload fields; incompatible peer/client protobuf versions producing empty responses; unit-test mocks that forget to populate the Response field.

Related errors


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