nautechsystems/nautilus_trader · error · anyhow::Error
{e}
Error message
{e} What it means
Raised in `spawn_message_handler` on the Kraken spot execution client when acquiring the WebSocket message stream (`self.ws.stream()`) fails; the underlying error is re-wrapped with `anyhow::anyhow!("{e}")`. This happens during `connect()` before the message-handling task starts, so it indicates the WebSocket client could not produce its receive stream at all.
Source
Thrown at crates/adapters/kraken/src/execution/spot.rs:588
.ok_or_else(|| anyhow::anyhow!("missing WS auth token"))?;
let params = build_cancel_order_params(cmd, token);
let identity = PendingRequest {
operation: PendingOperation::Cancel,
client_order_ids: vec![cmd.client_order_id],
venue_order_ids: vec![cmd.venue_order_id],
ts_sent_ns: 0,
new_quantity: None,
new_price: None,
new_trigger_price: None,
};
self.order_request_state
.cancel(params, identity, self.clock.get_time_ns().as_u64())?;
Ok(())
}
fn spawn_message_handler(&mut self) -> anyhow::Result<()> {
let stream = self.ws.stream().map_err(|e| anyhow::anyhow!("{e}"))?;
let emitter = self.emitter.clone();
let instruments = self.instruments.clone();
let order_qty_cache = self.order_qty_cache.clone();
let truncated_id_map = self.truncated_id_map.clone();
let dispatch_state = self.ws_dispatch_state.clone();
let order_request_state = self.order_request_state.clone();
let account_id = self.core.account_id;
let clock = self.clock;
let cancellation_token = self.cancellation_token.clone();
let future = async move {
tokio::pin!(stream);
loop {
tokio::select! {
() = cancellation_token.cancelled() => {
log::debug!("Spot execution message handler cancelled");
break;View on GitHub (pinned to 18893faf8b)
Solutions
- Read the wrapped `{e}` message for the underlying websocket library's failure reason.
- Do not call `connect()` twice on the same client instance; disconnect first or create a fresh client.
- Check network/proxy/DNS reachability to Kraken's WS endpoint.
- Recreate the execution client if its internal WS actor has terminated, then reconnect.
Example fix
// before
client.connect()?;
client.connect()?; // second call: stream already taken -> error
// after
if !client.is_connected() {
client.connect()?;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Guard against double-connect.
if client.is_connected() {
return Ok(()); // already streaming
} Try / catch
match client.connect() {
Ok(()) => (),
Err(e) => {
log::error!("kraken exec connect failed: {e}; recreating client");
client = KrakenExecClient::new(...)?;
client.connect()?;
}
} Prevention
- Call connect() only once per client instance; use is_connected() guards.
- Disconnect (or drop) a client before creating a new one for the same account.
- Validate network reachability to Kraken WS endpoints before connect.
- Recreate the client rather than re-connecting one whose WS actor has exited.
When it happens
Trigger: Calling `connect()` on the execution client when the underlying WS client is already shut down, its stream was already taken, or the WS library fails to initialize the stream (transport/socket setup failure).
Common situations: Double-connecting a client without disconnecting first; connecting after a previous connection was torn down and the WS actor exited; underlying websocket library/transport error during connection setup.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- L3 WebSocket failed to become active: {e}
- std::mem::take(&mut self.shutdown_errors).join("; ")
- WebSocket output receiver not available
- Coinbase WebSocket handler failed: {error}
- joined shutdown errors (std::mem::take(&mut self.shutdown_er
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/12eaff1361606cff.
Report an issue: GitHub.