hyperledger/fabric · error

request is nil

Error message

request is nil

What it means

BuildStepRequest converts an orderer.StepRequest (the etcdraft/consensus-facing message) into a ClusterNodeServiceStepRequest for the node-to-node service. It returns 'request is nil' when the incoming *orderer.StepRequest pointer is nil, as a defensive guard since there is no payload to convert.

Source

Thrown at orderer/common/cluster/commauth.go:300

	}

	payload.Signature = sig
	stepRequest := &orderer.ClusterNodeServiceStepRequest{
		Payload: &orderer.ClusterNodeServiceStepRequest_NodeAuthrequest{
			NodeAuthrequest: payload,
		},
	}

	return cs.StepClient.Send(stepRequest)
}

func (cs *NodeClientStream) Context() context.Context {
	return cs.StepClient.Context()
}

func BuildStepRequest(request *orderer.StepRequest) (*orderer.ClusterNodeServiceStepRequest, error) {
	if request == nil {
		return nil, errors.New("request is nil")
	}
	var stepRequest *orderer.ClusterNodeServiceStepRequest
	if consReq := request.GetConsensusRequest(); consReq != nil {
		stepRequest = &orderer.ClusterNodeServiceStepRequest{
			Payload: &orderer.ClusterNodeServiceStepRequest_NodeConrequest{
				NodeConrequest: &orderer.NodeConsensusRequest{
					Payload:  consReq.Payload,
					Metadata: consReq.Metadata,
				},
			},
		}
		return stepRequest, nil
	} else if subReq := request.GetSubmitRequest(); subReq != nil {
		stepRequest = &orderer.ClusterNodeServiceStepRequest{
			Payload: &orderer.ClusterNodeServiceStepRequest_NodeTranrequest{
				NodeTranrequest: &orderer.NodeTransactionOrderRequest{
					Payload:           subReq.Payload,
					LastValidationSeq: subReq.LastValidationSeq,

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Fix the caller so it never invokes Send with a nil request; propagate errors from whatever produced the StepRequest instead of sending nil.
  2. Add a nil check at the call site before calling Send and handle the failure there.
  3. Log the origin of the nil request to find the producer returning nil.

Example fix

// before
err := stream.Send(req) // req may be nil
// after
if req == nil {
    return fmt.Errorf("cannot send nil step request")
}
err := stream.Send(req)
Defensive patterns

Strategy: type-guard

Validate before calling

if request == nil {
    return errors.New("refusing to send nil StepRequest")
}
err := stream.Send(request)

Type guard

func isValidStepRequest(r *orderer.StepRequest) bool {
    return r != nil && r.GetPayload() != nil
}

Try / catch

if err := stream.Send(req); err != nil {
    if err.Error() == "request is nil" {
        log.Errorf("nil step request from producer")
    }
    return err
}

Prevention

When it happens

Trigger: Calling Send() on a NodeClientStream with a nil *orderer.StepRequest, or calling BuildStepRequest(nil) directly.

Common situations: Upstream producer of StepRequest failed silently and returned nil without error; mismanaged pointer in a dispatch loop that forwards consensus/submit requests; tests passing nil fixtures.

Related errors


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