hyperledger/fabric · error

received nil proposal response

Error message

received nil proposal response

What it means

This error is returned by ReadinessCheck after c.EndorserClient.ProcessProposal returns a nil proposal response without an error. The gRPC endorser client contract normally guarantees either a non-nil response or an error, so a nil response indicates an unexpected client state (e.g. the client was closed or a misbehaving interceptor/dial returned nothing). The library guards against dereferencing a nil pointer here.

Source

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

	proposal, err := c.createProposal(c.Input.TxID)
	if err != nil {
		return errors.WithMessage(err, "failed to create proposal")
	}

	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")
		}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the peer connection is alive: check tlsRootCertFile, peer address, and that EndorserClient was created from an open ClientConn
  2. Recreate the endorser client / redial the peer and retry the checkcommitreadiness command
  3. If using a mock or custom interceptor for EndorserClient, fix it to return a valid proposal response or a non-nil error

Example fix

// before
client, err := chaincode.NewEndorserClient(endpoint, tlsRootCert) // conn closed later
resp, _ := client.ProcessProposal(ctx, sp) // nil response
// after
if err := client.CheckConnection(); err != nil {
    client, err = chaincode.NewEndorserClient(endpoint, tlsRootCert) // redial before use
}
resp, err := client.ProcessProposal(ctx, sp)
if err != nil || resp == nil { return err }
Defensive patterns

Strategy: retry

Validate before calling

// check client connectivity before issuing proposal
if c.EndorserClient == nil {
    return errors.New("endorser client not initialized; recreate the client")
}

Try / catch

resp, err := c.EndorserClient.ProcessProposal(ctx, signedProposal)
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: ProcessProposal on the endorser gRPC client returns (nil, nil) — typically when the ClientConn/connection was already closed or torn down mid-call, or a custom dialer/interceptor short-circuits and returns nil responses.

Common situations: Peer connection dropped or client closed before the readiness query; tests stubbing EndorserClient incorrectly; gRPC transport failure surfaces as nil instead of error via custom plumbing.

Related errors


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