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
- Upgrade all nodes to a Fabric version that supports cluster node authentication (v3.x era consensus changes) so senders populate NodeAuthrequest.
- Ensure the Step client sets the oneof to NodeAuthrequest first (authentication handshake) before Submit requests.
- Check for intermediaries (proxies, service meshes) rewriting or dropping gRPC message fields.
- 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
- Run homogeneous Fabric versions across cluster nodes and peers
- Ensure step clients perform the auth handshake before Submit requests
- Audit proxies/service meshes for gRPC message rewriting
- Add integration tests covering node-to-node Step authentication
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
- session binding read failed
- failed to create new stream
- access denied, client identity wasn't supplied
- session binding mismatch
- node %d doesn't exist in channel %s's membership
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/729b00a94a9643ab.
Report an issue: GitHub.