{"record":{"id":"315f63b8b3f233eb","repo":"rustdesk/rustdesk","slug":"connection-manager-window-closed","errorCode":null,"errorMessage":"Connection manager window closed","messagePattern":"Connection manager window closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/server/connection.rs","lineNumber":1253,"sourceCode":"    ) -> ResultType<()> {\n        let mut last_recv_time = Instant::now();\n        if let Some(mut forward) = self.port_forward_socket.take() {\n            log::info!(\"Running port forwarding loop\");\n            self.stream.set_raw();\n            let mut hbbs_rx = crate::hbbs_http::sync::signal_receiver();\n            loop {\n                tokio::select! {\n                    Some(data) = rx_from_cm.recv() => {\n                        match data {\n                            ipc::Data::Close => {\n                                bail!(\"Close requested from connection manager\");\n                            }\n                            // Same end as above: a tunnel must not outlive the window either.\n                            // Only the reason differs, and a port forward carries none - the\n                            // peer sees the tunnel drop and decides for itself.\n                            #[cfg(target_os = \"linux\")]\n                            ipc::Data::CmWindowClosed => {\n                                bail!(\"Connection manager window closed\");\n                            }\n                            ipc::Data::CmErr(e) => {\n                                log::error!(\"Connection manager error: {e}\");\n                                bail!(\"{e}\");\n                            }\n                            _ => {}\n                        }\n                    }\n                    res = forward.next() => {\n                        if let Some(res) = res {\n                            last_recv_time = Instant::now();\n                            self.stream.send_bytes(res?.into()).await?;\n                        } else {\n                            bail!(\"Forward reset by the peer\");\n                        }\n                    },\n                    res = self.stream.next() => {\n                        if let Some(res) = res {","sourceCodeStart":1235,"sourceCodeEnd":1271,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540/src/server/connection.rs#L1235-L1271","documentation":"On Linux, if the connection manager window is closed, any tunnel spawned from it is also terminated: the select loop receives ipc::Data::CmWindowClosed and bails with this message. The design intent is that a tunnel must not outlive the cm window; the peer sees the drop and decides for itself.","triggerScenarios":"Linux only: the user closes the RustDesk connection manager window while a port-forward/tunnel is active, causing cm to notify child connections via Data::CmWindowClosed.","commonSituations":"Closing the cm window while a port forward is still in use; cm crash/window teardown on Linux desktop; session cleanup scripts closing the window.","solutions":["Keep the connection manager window open while tunnels are needed","Re-establish the port forward after reopening the cm window","If tunnels must survive window close, this requires a design change (currently intentional on Linux)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// linux only: confirm cm window is still open before relying on a tunnel\n#[cfg(target_os = \"linux\")]\nif !cm_window_alive() {\n    return Err(anyhow!(\"cm window closed; tunnel will be dropped\"));\n}","typeGuard":null,"tryCatchPattern":"match tunnel_result {\n    Err(e) if e.to_string() == \"Connection manager window closed\" => {\n        log::info!(\"tunnel ended because cm window closed\");\n        // optionally re-establish after reopening cm\n    }\n    other => other,\n}","preventionTips":["Keep the cm window open while port forwards are active on Linux","Recreate tunnels after reopening the cm window","Do not treat this as a network fault"],"tags":["linux","ipc","tunnel","lifecycle","window"],"backgroundTag":"invalid-state-transition","analyzedSha":"91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540","analyzedAt":"2026-09-10T19:53:44.083Z","contentChangedAt":"2026-09-10T19:53:44.083Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}