{"record":{"id":"8e4c4d1e5652d49a","repo":"netbirdio/netbird","slug":"receive-expose-event-v","errorCode":null,"errorMessage":"receive expose event: %v","messagePattern":"receive expose event: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/expose.go","lineNumber":240,"sourceCode":"\tcase expose.ProtocolHTTP:\n\t\treturn proto.ExposeProtocol_EXPOSE_HTTP, nil\n\tcase expose.ProtocolHTTPS:\n\t\treturn proto.ExposeProtocol_EXPOSE_HTTPS, nil\n\tcase expose.ProtocolTCP:\n\t\treturn proto.ExposeProtocol_EXPOSE_TCP, nil\n\tcase expose.ProtocolUDP:\n\t\treturn proto.ExposeProtocol_EXPOSE_UDP, nil\n\tcase expose.ProtocolTLS:\n\t\treturn proto.ExposeProtocol_EXPOSE_TLS, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"unhandled protocol type: %d\", p)\n\t}\n}\n\nfunc handleExposeReady(cmd *cobra.Command, stream proto.DaemonService_ExposeServiceClient, port uint64) error {\n\tevent, err := stream.Recv()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"receive expose event: %v\", status.Convert(err).Message())\n\t}\n\n\tready, ok := event.Event.(*proto.ExposeServiceEvent_Ready)\n\tif !ok {\n\t\treturn fmt.Errorf(\"unexpected expose event: %T\", event.Event)\n\t}\n\tprintExposeReady(cmd, ready.Ready, port)\n\treturn nil\n}\n\nfunc printExposeReady(cmd *cobra.Command, r *proto.ExposeServiceReady, port uint64) {\n\tcmd.Println(\"Service exposed successfully!\")\n\tcmd.Printf(\"  Name:     %s\\n\", r.ServiceName)\n\tif r.ServiceUrl != \"\" {\n\t\tcmd.Printf(\"  URL:      %s\\n\", r.ServiceUrl)\n\t}\n\tif r.Domain != \"\" && !isPortBasedProtocol(exposeProtocol) {\n\t\tcmd.Printf(\"  Domain:   %s\\n\", r.Domain)","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/expose.go#L222-L258","documentation":"The first stream.Recv() on the server-streamed ExposeService call returned a gRPC error instead of the Ready event. Unlike the initial-RPC failure, the call was accepted and the stream opened — this error means the daemon failed (or the transport broke) while setting the exposure up and sending its first event. The gRPC status message is surfaced.","triggerScenarios":"The daemon encounters a setup failure after accepting the RPC (proxy-cluster allocation error, management rejection) and sends an error status before Ready; the daemon process dies mid-setup; the context is canceled — exposeFn cancels ctx on SIGINT/SIGTERM, making Recv return context.Canceled; an IPC/socket failure on the open stream.","commonSituations":"Pressing Ctrl+C while waiting for the 'Service exposed successfully!' line; transient cluster allocation failures; daemon crash or restart during exposure setup; flaky daemon-to-management connectivity on the server side.","solutions":["Check the daemon log at the failure timestamp for the server-side reason (it usually knows more than the status message)","Re-run the command — transient allocation and stream errors typically clear on retry","If it fails consistently, verify daemon-to-management connectivity and that the account's services feature works (e.g. `netbird status` healthy, dashboard shows services)","Avoid sending SIGINT before the Ready event is printed; wait for the success line before interrupting"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"event, err := stream.Recv()\nif err != nil {\n\tif ctx.Err() != nil || status.Code(err) == codes.Canceled {\n\t\treturn fmt.Errorf(\"expose interrupted before ready: %w\", err)\n\t}\n\t// daemon-side setup failure before the Ready event; its log has the reason\n\treturn fmt.Errorf(\"receive expose event: %s\", status.Convert(err).Message())\n}","preventionTips":["Do not send SIGINT/SIGTERM while waiting for the Ready line — exposeFn cancels the stream and produces this error","Re-run once on transient failures before investigating; allocation errors are often momentary","Correlate with the daemon log timestamp when the message is generic","Keep daemon and management versions compatible so setup-side rejections are rare"],"tags":["grpc","server-stream","expose","context-canceled","netbird-cli"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}