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

  1. If in tests, fix the mock to return a valid ProposalResponse
  2. Inspect interceptors/proxies wrapping the endorser client that may swallow responses
  3. 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

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


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