{"record":{"id":"f7bcd86fff7075fb","repo":"hyperledger/fabric","slug":"signer-is-nil","errorCode":null,"errorMessage":"signer is nil","messagePattern":"signer is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/commauth.go","lineNumber":252,"sourceCode":"func (cs *NodeClientStream) Send(request *orderer.StepRequest) error {\n\tstepRequest, cerr := BuildStepRequest(request)\n\tif cerr != nil {\n\t\treturn cerr\n\t}\n\treturn cs.StepClient.Send(stepRequest)\n}\n\nfunc (cs *NodeClientStream) Recv() (*orderer.StepResponse, error) {\n\tnodeResponse, err := cs.StepClient.Recv()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn BuildStepRespone(nodeResponse)\n}\n\nfunc (cs *NodeClientStream) Auth() error {\n\tif cs.Signer == nil {\n\t\treturn errors.New(\"signer is nil\")\n\t}\n\n\tpayload := &orderer.NodeAuthRequest{\n\t\tVersion:   cs.Version,\n\t\tTimestamp: timestamppb.Now(),\n\t\tFromId:    cs.SourceNodeID,\n\t\tToId:      cs.DestinationNodeID,\n\t\tChannel:   cs.Channel,\n\t}\n\n\tbindingFieldsHash := GetSessionBindingHash(payload)\n\n\ttlsBinding, err := GetTLSSessionBinding(cs.StepClient.Context(), bindingFieldsHash)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"TLSBinding failed\")\n\t}\n\tpayload.SessionBinding = tlsBinding\n","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/commauth.go#L234-L270","documentation":"NodeClientStream.Auth() requires an identity.Signer to authenticate the stream to the remote cluster node. Before building the NodeAuthRequest it checks cs.Signer and returns this error if the Signer field of NodeClientStream is nil. It is a programming/configuration guard: the stream was constructed without the signing identity needed to sign the auth payload.","triggerScenarios":"Calling Auth() on a NodeClientStream whose Signer field was never populated when the stream struct was constructed (NodeClientStream{StepClient: ..., ...} built without assigning an identity.Signer).","commonSituations":"Test harnesses or custom RPC stream factories that construct NodeClientStream manually and forget the Signer; code paths where a service identity was not loaded (missing MSP config / signing identity) so nil is passed in; refactors that dropped the Signer assignment.","solutions":["Populate the Signer field when constructing NodeClientStream with a valid identity.Signer obtained from the local MSP/signing identity manager.","Check where the stream is created and ensure the signing identity loaded successfully before wiring it into the stream.","If Auth() is not needed for the stream's purpose, do not call it instead of leaving Signer nil."],"exampleFix":"// before\nstream := &cluster.NodeClientStream{\n    StepClient: stepClient,\n    Version:    1,\n}\nstream.Auth() // panics-free but returns \"signer is nil\"\n// after\nsigner, err := localmsp.NewSigner()\nif err != nil {\n    return err\n}\nstream := &cluster.NodeClientStream{\n    StepClient: stepClient,\n    Version:    1,\n    Signer:     signer,\n}\nstream.Auth()","handlingStrategy":"validation","validationCode":"if stream == nil || stream.Signer == nil {\n    return errors.New(\"cannot authenticate: stream has no signer configured\")\n}\nerr := stream.Auth()","typeGuard":"func hasSigner(cs *cluster.NodeClientStream) bool {\n    return cs != nil && cs.Signer != nil\n}","tryCatchPattern":"if err := stream.Auth(); err != nil {\n    if err.Error() == \"signer is nil\" {\n        // re-create stream with a valid signer\n    }\n    return fmt.Errorf(\"auth: %w\", err)\n}","preventionTips":["Always construct NodeClientStream via a factory that injects the signing identity.","Fail fast at startup if the local MSP signing identity cannot be loaded.","Add unit tests covering Auth() for streams built without a Signer."],"tags":["fabric","authentication","nil-pointer","signer"],"backgroundTag":"missing-signing-identity","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}