{"record":{"id":"c58738261af7217a","repo":"nautechsystems/nautilus_trader","slug":"subscription-confirmation-failed-e","errorCode":null,"errorMessage":"subscription confirmation failed: {e}","messagePattern":"subscription confirmation failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/deribit/src/execution.rs","lineNumber":578,"sourceCode":"            self.ws_client\n                .subscribe_user_orders()\n                .await\n                .map_err(|e| anyhow::anyhow!(\"failed to subscribe to user orders: {e}\"))?;\n            self.ws_client\n                .subscribe_user_trades()\n                .await\n                .map_err(|e| anyhow::anyhow!(\"failed to subscribe to user trades: {e}\"))?;\n            self.ws_client\n                .subscribe_user_portfolio()\n                .await\n                .map_err(|e| anyhow::anyhow!(\"failed to subscribe to user portfolio: {e}\"))?;\n\n            if let Err(e) = self.ws_client.wait_for_subscriptions_confirmed(30.0).await {\n                // Roll back subscription state so a retry re-sends subscribe requests\n                let _ = self.ws_client.unsubscribe_user_orders().await;\n                let _ = self.ws_client.unsubscribe_user_trades().await;\n                let _ = self.ws_client.unsubscribe_user_portfolio().await;\n                anyhow::bail!(\"subscription confirmation failed: {e}\");\n            }\n\n            log::debug!(\"Subscribed to user order, trade, and portfolio updates\");\n\n            // Spawn stream handler to dispatch WebSocket messages to the execution engine\n            let stream = self.ws_client.stream()?;\n            self.spawn_stream_handler(stream)?;\n\n            Ok::<(), anyhow::Error>(())\n        }\n        .await;\n\n        if let Err(e) = session_result {\n            if let Err(teardown_error) = self.teardown_partial_connect().await {\n                return Err(e.context(format!(\n                    \"Deribit execution startup teardown failed: {teardown_error}\"\n                )));\n            }","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/deribit/src/execution.rs#L560-L596","documentation":"The Deribit execution client subscribes to user order, trade, and portfolio channels during connect; this error is raised when the WebSocket client does not receive subscription confirmations within the 30-second timeout. On failure it unsubscribes from all three channels so a reconnect retry re-sends the subscribe requests cleanly.","triggerScenarios":"Calling connect when the Deribit WebSocket does not confirm all subscriptions (private/orders, private/trades, private/portfolio) within 30 seconds — typically due to network issues, slow Deribit API response, or failed authentication preventing private channel subscription.","commonSituations":"Deribit outage or degraded WebSocket service; expired API credentials so private channels are rejected; corporate proxy/firewall dropping or delaying WS frames; very slow network causing confirmation to arrive after the 30s window.","solutions":["Verify Deribit API credentials are valid and test auth separately before connecting","Check network connectivity and any proxy/firewall that may block or delay WebSocket frames","Check Deribit status (outages/degraded service) and retry connect after unsubscribed rollback","Increase tolerance by retrying connect — subscription state is rolled back so a retry re-subscribes correctly"],"exampleFix":"// before\nlet client = DeribitExecutionClient::new(...); // connect() may bail on confirmation timeout\nclient.connect().await?;\n// after\nfor attempt in 0..3 {\n    match client.connect().await {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"subscription confirmation failed\") && attempt < 2 => {\n            log::warn!(\"retrying connect after subscription failure: {e}\");\n            tokio::time::sleep(Duration::from_secs(5)).await;\n        }\n        Err(e) => return Err(e),\n    }\n}","handlingStrategy":"retry","validationCode":"// Before connecting, verify credentials and reachability\nlet creds = std::env::var(\"DERIBIT_API_KEY\")?;\nassert!(!creds.is_empty());\n// optionally ping Deribit REST: GET https://www.deribit.com/api/v2/public/test","typeGuard":null,"tryCatchPattern":"match client.connect().await {\n    Err(e) if e.to_string().contains(\"subscription confirmation failed\") => retry_with_backoff(3),\n    other => other,\n}","preventionTips":["Validate API credentials before connect so private channels subscribe successfully","Monitor Deribit status pages and avoid connecting during known outages","Keep connect retries with backoff — the client rolls back subscription state for clean retry","Test WebSocket connectivity through any corporate proxy before production use"],"tags":["websocket","network","timeout","subscription","deribit"],"backgroundTag":"request-timeout","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"}