nautechsystems/nautilus_trader · error

Failed to connect to Tardis Machine: {e}

Error message

Failed to connect to Tardis Machine: {e}

What it means

Raised in connect when the initial WebSocket handshake to the Tardis Machine fails (connect_async returns Err). The client cannot establish the WS connection to the local/remote Tardis Machine endpoint.

Source

Thrown at crates/adapters/tardis/src/data.rs:578

            .bootstrap_instruments(&exchanges)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to bootstrap instruments: {e}"))?;

        for instrument in instruments {
            if let Err(e) = self.data_sender.send(DataEvent::Instrument(instrument)) {
                log::error!("Failed to send instrument event: {e}");
            }
        }

        let url = self.build_ws_url(&base_url)?;

        let mode_label = if is_stream_mode { "stream" } else { "replay" };
        log::info!("Connecting to Tardis Machine {mode_label}");
        log::debug!("URL: {url}");

        let (ws_stream, _) = connect_async(&url)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to connect to Tardis Machine: {e}"))?;

        log::info!("Connected to Tardis Machine");

        if let Err(e) = self.spawn_ws_task(
            ws_stream,
            url,
            instrument_map,
            book_snapshot_output,
            extract_bbo_as_quotes,
            is_stream_mode,
        ) {
            self.tasks.begin_shutdown();
            if let Err(teardown_error) = self
                .tasks
                .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
                .await
            {
                return Err(e.context(format!("Tardis startup teardown failed: {teardown_error}")));

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Confirm Tardis Machine is running and reachable (docker ps / curl its health endpoint).
  2. Check the configured URL: correct host, port, and ws:// (or wss://) scheme.
  3. Verify no firewall or proxy blocks the WebSocket connection.
  4. Check `{e}`: 'Connection refused' means wrong port/host or service down.

Example fix

// before
url: "http://localhost:8000".into(),
// after: WebSocket endpoint, not http
url: "ws://localhost:8000".into(),
Defensive patterns

Strategy: validation

Validate before calling

// Reachability + scheme pre-check before connecting
let url = config.machine_url.clone();
anyhow::ensure!(url.starts_with("ws://") || url.starts_with("wss://"), "machine URL must be ws(s)://, got {url}");
let host = url.trim_start_matches("ws://").trim_start_matches("wss://");
tokio::net::TcpStream::connect(host).await?; // fails fast if Tardis Machine is down

Try / catch

match client.connect().await {
    Err(e) if e.to_string().contains("Failed to connect to Tardis Machine") => {
        log::error!("is Tardis Machine running at the configured URL? {e}");
        // restart the machine container, then retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: connect_async(&url) fails: Tardis Machine not running, wrong host/port in config, TLS failure, connection refused/timeout, or invalid URL scheme.

Common situations: Tardis Machine Docker container not started or not listening on the configured port; wrong machine URL (http vs ws scheme); firewall/proxy blocking the connection.

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/825c55a8a0103d9a. Report an issue: GitHub.