nautechsystems/nautilus_trader · error

WS session authentication timed out

Error message

WS session authentication timed out

What it means

The Binance Spot WebSocket trading session was authenticated (listenKey flow) but no WS setup/response message arrived before the configured timeout, so wait_for_ws_setup_response converts the empty result into this error. Without the setup response the trading stream cannot be used, so connect() aborts.

Solutions

  1. Increase the WS setup timeout value used when connecting
  2. Check network connectivity / proxy settings to wss:// endpoints for the configured Binance cluster
  3. Retry connect() — this is transient under exchange load
  4. Verify the adapter targets the correct Binance URL (spot vs testnet) so the setup response arrives

Example fix

// before
let timeout_secs = 5;
// after
let timeout_secs = 30; // allow for exchange latency/outages
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check network reachability of the WS endpoint before connect
// (e.g. TCP connect to the wss host with a short timeout)

Try / catch

for attempt in 0..3 {
    match client.connect().await {
        Ok(()) => break,
        Err(e) if e.to_string().contains("authentication timed out") => {
            tokio::time::sleep(Duration::from_secs(2 * (attempt + 1))).await;
        },
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Binance WS endpoint unreachable or slow during connect(); the dispatched trading message never matched the setup-response variant; network latency exceeding the timeout used by wait_for_ws_setup_response.

Common situations: Binance API outage or regional blockage; firewall/proxy dropping wss connections; overly aggressive timeout configured; listenKey keep-alive failure mid-handshake.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/spot/execution.rs:2210

    setup_errors: &mut tokio::sync::mpsc::UnboundedReceiver<String>,
    timeout_message: &'static str,
) -> anyhow::Result<()> {
    tokio::pin!(success);

    let result = tokio::time::timeout(timeout, async {
        tokio::select! {
            () = &mut success => Ok(()),
            err = setup_errors.recv() => {
                anyhow::bail!(
                    "{}",
                    err.unwrap_or_else(|| "WS setup error channel closed".to_string()),
                )
            }
        }
    })
    .await;

    result.map_err(|_| anyhow::anyhow!(timeout_message))?
}

#[expect(clippy::too_many_arguments)]
fn dispatch_ws_trading_message(
    msg: BinanceSpotWsTradingMessage,
    emitter: &ExecutionEventEmitter,
    http_client: &BinanceSpotHttpClient,
    account_id: AccountId,
    treat_expired_as_canceled: bool,
    clock: &'static AtomicTime,
    dispatch_state: &WsDispatchState,
    ws_authenticated: &tokio::sync::Notify,
    ws_user_data_subscribed: &tokio::sync::Notify,
    ws_setup_error_tx: &tokio::sync::mpsc::UnboundedSender<String>,
    seen_trade_ids: &std::sync::Arc<Mutex<FifoCache<(Ustr, i64), 10_000>>>,
    task_spawner: &TaskSpawner,
) {
    match msg {

View on GitHub (pinned to 18893faf8b)