{"record":{"id":"f7f9e9aecdc3100f","repo":"rustdesk/rustdesk","slug":"closed-manually-by-the-web-console","errorCode":null,"errorMessage":"Closed manually by the web console","messagePattern":"Closed manually by the web console","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/server/connection.rs","lineNumber":1286,"sourceCode":"                        }\n                    },\n                    res = self.stream.next() => {\n                        if let Some(res) = res {\n                            last_recv_time = Instant::now();\n                            timeout(SEND_TIMEOUT_OTHER, forward.send(res?)).await??;\n                        } else {\n                            bail!(\"Stream reset by the peer\");\n                        }\n                    },\n                    _ = self.timer.tick() => {\n                        if last_recv_time.elapsed() >= H1 {\n                            bail!(\"Timeout\");\n                        }\n                    }\n                    Ok(conns) = hbbs_rx.recv() => {\n                        if conns.contains(&self.inner.id) {\n                            // todo: check reconnect\n                            bail!(\"Closed manually by the web console\");\n                        }\n                    }\n                }\n            }\n        }\n        Ok(())\n    }\n\n    async fn send_permission(&mut self, permission: Permission, enabled: bool) {\n        let mut misc = Misc::new();\n        misc.set_permission_info(PermissionInfo {\n            permission: permission.into(),\n            enabled,\n            ..Default::default()\n        });\n        let mut msg_out = Message::new();\n        msg_out.set_misc(misc);\n        self.send(msg_out).await;","sourceCodeStart":1268,"sourceCodeEnd":1304,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540/src/server/connection.rs#L1268-L1304","documentation":"Raised when a message received on `hbbs_rx` (the channel from the rendezvous/signaling server) indicates this connection's id is in a list of connections to close — i.e., an operator closed the session via the web console. The error is intentional administrative termination, not a fault.","triggerScenarios":"An administrator selects 'close connection' for this peer's id in the web console; the `hbbs_rx.recv()` branch receives `Ok(conns)` whose vector contains `self.inner.id`.","commonSituations":"IT admin terminates a user's remote session from the management console; compliance policy auto-kills sessions; mistaken closure targeting the wrong id.","solutions":["Confirm with the admin/console operator that the session was intentionally closed","Have the client detect this specific error and show 'session closed by administrator' instead of a generic failure","Implement the pending 'check reconnect' TODO to auto-reconnect when appropriate","Audit console access logs to rule out unauthorized closures"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match session_result {\n    Err(e) if e.to_string().contains(\"Closed manually by the web console\") =>\n        show_admin_closed_notice(),\n    other => propagate(other),\n}","preventionTips":["Coordinate with console admins before closing sessions","Map this error to a distinct UI message","Audit console close actions"],"tags":["admin","web-console","session-termination"],"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"}