{"record":{"id":"b37bcab140fd7bdb","repo":"nautechsystems/nautilus_trader","slug":"failed-to-disconnect-data-clients-data-err-fai","errorCode":null,"errorMessage":"Failed to disconnect data clients: {data_err}; failed to disconnect execution clients: {exec_err}","messagePattern":"Failed to disconnect data clients: (.+?); failed to disconnect execution clients: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/system/src/kernel.rs","lineNumber":1095,"sourceCode":"\n    /// Disconnects all engine clients.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if any client fails to disconnect.\n    #[expect(clippy::await_holding_refcell_ref)] // Single-threaded runtime, intentional design\n    pub async fn disconnect_clients(&mut self) -> anyhow::Result<()> {\n        log::info!(\"Disconnecting clients...\");\n        let mut data_engine = self.data_engine.borrow_mut();\n        let mut exec_engine = self.exec_engine.borrow_mut();\n        let (data_result, exec_result) =\n            futures::join!(data_engine.disconnect(), exec_engine.disconnect());\n\n        match (data_result, exec_result) {\n            (Ok(()), Ok(())) => Ok(()),\n            (Err(data_err), Ok(())) => Err(data_err),\n            (Ok(()), Err(exec_err)) => Err(exec_err),\n            (Err(data_err), Err(exec_err)) => anyhow::bail!(\n                \"Failed to disconnect data clients: {data_err}; failed to disconnect execution \\\n                 clients: {exec_err}\"\n            ),\n        }\n    }\n\n    /// Returns `true` if all engine clients are connected.\n    #[must_use]\n    pub fn check_engines_connected(&self) -> bool {\n        self.data_engine.borrow().check_connected() && self.exec_engine.borrow().check_connected()\n    }\n\n    /// Returns `true` if all engine clients are disconnected.\n    #[must_use]\n    pub fn check_engines_disconnected(&self) -> bool {\n        self.data_engine.borrow().check_disconnected()\n            && self.exec_engine.borrow().check_disconnected()\n    }","sourceCodeStart":1077,"sourceCodeEnd":1113,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/kernel.rs#L1077-L1113","documentation":"Kernel::disconnect_clients shuts down data and execution client connections concurrently via futures::join!. If both disconnect futures fail, neither error is preferred, so both are combined into one message identifying each side. A single failure is returned as-is; only the both-failed case produces this combined error.","triggerScenarios":"Calling kernel.disconnect_clients() (or node stop/shutdown) when both the data engine's and the execution engine's disconnect() fail — e.g. both venue WebSocket sessions are already dead or their clients error during teardown.","commonSituations":"Network outage at shutdown so both connections abort with transport errors; venue-side session termination; client cleanup code raising errors for both engines simultaneously.","solutions":["Inspect both halves of the message; fix the underlying transport/venue issue for each side separately","If clients are already dead, this may be benign — verify no orders/state were left dirty and continue shutdown","Add retry or timeout handling around disconnect if the venue is intermittently unreachable","Check client logs for whether disconnect errors indicate already-closed connections (often ignorable at teardown)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Probe connectivity before shutdown-sensitive operations\nlet data_ok = data_engine.ping().is_ok();\nlet exec_ok = exec_engine.ping().is_ok();\nlog::info!(\"disconnect pre-check: data_ok={data_ok} exec_ok={exec_ok}\");","typeGuard":null,"tryCatchPattern":"match kernel.disconnect_clients().await {\n    Err(e) if e.to_string().contains(\"Failed to disconnect data clients\") => {\n        // both sides failed; treat as best-effort teardown, log both halves\n        log::warn!(\"disconnect: {e}\");\n    }\n    other => other?,\n}","preventionTips":["Treat disconnect failures of dead connections as best-effort during teardown","Implement bounded retries with backoff in client disconnect paths","Monitor venue connectivity so failures at shutdown are anticipated"],"tags":["rust","kernel","shutdown","clients","network"],"backgroundTag":"network-request-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}