{"record":{"id":"54ef38bd921a6687","repo":"nautechsystems/nautilus_trader","slug":"authentication-failed-e-handler-shutdown-faile","errorCode":null,"errorMessage":"Authentication failed: {e}; handler shutdown failed: {shutdown_error}","messagePattern":"Authentication failed: (.+?); handler shutdown failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/client.rs","lineNumber":894,"sourceCode":"            control.register(move || reconnect_handle.request_reconnect());\n        }\n        log::debug!(\"Sent WebSocket client to handler\");\n\n        if self.credential.is_some()\n            && let Err(e) = self.authenticate().await\n        {\n            self.handler_tasks.begin_shutdown();\n            self.request_close().await;\n            let shutdown_result = self.close_stream_task(Duration::from_secs(2)).await;\n\n            if let Some(control) = &self.socket_control {\n                control.deregister();\n            }\n            self.out_rx = None;\n\n            match shutdown_result {\n                Ok(()) => anyhow::bail!(\"Authentication failed: {e}\"),\n                Err(shutdown_error) => anyhow::bail!(\n                    \"Authentication failed: {e}; handler shutdown failed: {shutdown_error}\"\n                ),\n            }\n        }\n\n        rollback.disarm();\n        Ok(())\n    }\n\n    /// Authenticates the WebSocket session with OKX.\n    async fn authenticate(&self) -> Result<(), Error> {\n        let credential = self.credential.as_ref().ok_or_else(|| {\n            Error::Io(std::io::Error::other(\n                \"API credentials not available to authenticate\",\n            ))\n        })?;\n\n        let rx = self.auth_tracker.begin();","sourceCodeStart":876,"sourceCodeEnd":912,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/client.rs#L876-L912","documentation":"This is the compound variant of the OKX WebSocket authentication failure: auth failed AND the subsequent handler-shutdown/teardown also failed, so both errors are reported together. It surfaces the original auth error plus the shutdown error to avoid hiding either failure during rollback.","triggerScenarios":"Same as the plain auth failure ([1038]) — failed OKX login during `connect()` with credentials — combined with the cleanup path (`begin_shutdown`/`close_stream_task`) returning an error, e.g. because the handler task was already dead or timed out.","commonSituations":"Invalid credentials plus a racing handler-task crash; shutdown timeout (2s) exceeded while the socket is wedged; calling connect during runtime teardown where both auth and cleanup fail.","solutions":["Fix the underlying credential problem first (see the auth failure: key/secret/passphrase, clock sync, permissions).","Investigate the appended `shutdown_error` — usually a handler task that already exited or a shutdown timeout.","After a failed rollback, recreate the client instance rather than reusing it, since internal state (socket control, out_rx) was reset.","Ensure connect/disconnect calls are serialized (await each fully) to avoid racing handler teardown."],"exampleFix":"// before: reusing a client whose teardown half-failed\nclient.connect().await?; // Authentication failed ... shutdown failed\n// after: rebuild after auth-fixing config change\nlet client = OKXWebSocketClient::new(key, secret, passphrase, ...).await?;\nclient.connect().await?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.connect().await {\n    Err(e) if e.to_string().starts_with(\"Authentication failed\") && e.to_string().contains(\"shutdown failed\") => {\n        log::error!(\"auth + rollback both failed; rebuild the client: {e}\");\n        client = build_new_client()?;\n    }\n    other => other?,\n}","preventionTips":["Fix the credential problem first — the shutdown error is secondary.","Recreate the client instance after this error; rollback state may be dirty.","Avoid concurrent connect/disconnect racing that makes teardown time out.","Increase awareness of the 2s shutdown windows; ensure the runtime is responsive."],"tags":["okx","websocket","authentication","shutdown"],"backgroundTag":"authentication-required","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}