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

  1. Read the wrapped `{e}` message for the underlying websocket library's failure reason.
  2. Do not call `connect()` twice on the same client instance; disconnect first or create a fresh client.
  3. Check network/proxy/DNS reachability to Kraken's WS endpoint.
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/12eaff1361606cff. Report an issue: GitHub.