hyperledger/fabric · error

invalid request object

Error message

invalid request object

What it means

ClusterService.VerifyAuthRequest authenticates node-to-node (cluster) Step requests. It expects the request to carry a NodeAuthRequest oneof (request.GetNodeAuthrequest()). This error means the incoming request did not contain the authentication message at all, so no signature/TLS-binding verification can proceed.

Source

Thrown at orderer/common/cluster/clusterservice.go:125

	}()

	for {
		err := s.handleMessage(stream, addr, exp, authReq.Channel, authReq.FromId, streamID)
		if err == io.EOF {
			s.Logger.Debugf("%s(%s) disconnected", commonName, addr)
			return nil
		}
		if err != nil {
			return err
		}
		// Else, no error occurred, so we continue to the next iteration
	}
}

func (s *ClusterService) VerifyAuthRequest(stream orderer.ClusterNodeService_StepServer, request *orderer.ClusterNodeServiceStepRequest) (*orderer.NodeAuthRequest, error) {
	authReq := request.GetNodeAuthrequest()
	if authReq == nil {
		return nil, errors.New("invalid request object")
	}

	bindingFieldsHash := GetSessionBindingHash(authReq)

	tlsBinding, err := GetTLSSessionBinding(stream.Context(), bindingFieldsHash)
	if err != nil {
		return nil, errors.Wrap(err, "session binding read failed")
	}

	if !bytes.Equal(tlsBinding, authReq.SessionBinding) {
		return nil, errors.New("session binding mismatch")
	}

	msg, err := asn1.Marshal(AuthRequestSignature{
		Version:        int64(authReq.Version),
		Timestamp:      EncodeTimestamp(authReq.Timestamp),
		FromId:         strconv.FormatUint(authReq.FromId, 10),
		ToId:           strconv.FormatUint(authReq.ToId, 10),

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Upgrade all nodes to a Fabric version that supports cluster node authentication (v3.x era consensus changes) so senders populate NodeAuthrequest.
  2. Ensure the Step client sets the oneof to NodeAuthrequest first (authentication handshake) before Submit requests.
  3. Check for intermediaries (proxies, service meshes) rewriting or dropping gRPC message fields.
  4. Reproduce with a minimal gRPC client and inspect which oneof variant is actually set before sending.

Example fix

// before
req := &orderer.StepRequest{Payload: &orderer.StepRequest_SubmitRequest{...}} // auth missing
// after
req := &orderer.StepRequest{Payload: &orderer.StepRequest_NodeAuthrequest{NodeAuthrequest: authReq}}
Defensive patterns

Strategy: try-catch

Validate before calling

if req.GetNodeAuthrequest() == nil {
    return errors.New("StepRequest must carry the NodeAuthrequest oneof variant")
}

Type guard

func isAuthRequest(req *orderer.ClusterNodeServiceStepRequest) bool {
    return req != nil && req.GetNodeAuthrequest() != nil
}

Try / catch

authReq, err := svc.VerifyAuthRequest(stream, request)
if err != nil {
    if strings.Contains(err.Error(), "invalid request object") {
        // sender is not populating the auth oneof — check version/config
    }
    return err
}

Prevention

When it happens

Trigger: A node (or step-client such as osnadmin/consenter tooling) sends a StepRequest whose oneof payload is the Submit/SubmitRequest variant instead of NodeAuthrequest, or an empty request; a peer running older Fabric code that predates cluster node authentication talking to a newer orderer.

Common situations: Version skew between ordering nodes or between peer and orderer after an upgrade; misconfigured cluster senders; a load balancer or proxy stripping/replacing the gRPC message; manual gRPC testing that omits the auth field.

Related errors


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