nautechsystems/nautilus_trader · error · anyhow::Error

Binance Spot user data stream is not active

Error message

Binance Spot user data stream is not active

What it means

The execution client refuses to accept orders unless its private user data stream is live: for binance.us routing the ws_user_data_client/handle must be active, otherwise the WS trading session's user data must be marked active and its dispatch task still running (spot/execution.rs:266-295). Without the user data stream the client would never observe fills, so submit_order and submit_order_list fail fast via ensure_ws_user_data_active.

Source

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

            self.ws_trading_handle
                .as_ref()
                .is_some_and(|handle| !handle.is_finished())
        };
        let user_data_active = if self.config.us {
            self.ws_user_data_client
                .as_ref()
                .is_some_and(BinanceSpotWsTradingClient::is_user_data_active)
        } else {
            self.ws_trading_client
                .as_ref()
                .is_some_and(BinanceSpotWsTradingClient::is_user_data_active)
        };

        user_data_active && dispatch_running
    }

    fn ensure_ws_user_data_active(&self) -> anyhow::Result<()> {
        anyhow::ensure!(
            self.ws_user_data_active(),
            "Binance Spot user data stream is not active",
        );
        Ok(())
    }

    fn ws_order_transport_active(&self) -> bool {
        self.config.use_ws_trading && self.ws_trading_client.is_some() && self.ws_user_data_active()
    }

    fn submit_order_internal(&self, cmd: &SubmitOrder) -> anyhow::Result<()> {
        let order = self.core.cache().try_order_owned(&cmd.client_order_id)?;

        let event_emitter = self.emitter.clone();
        let trader_id = self.core.trader_id;
        let account_id = self.core.account_id;
        let client_order_id = order.client_order_id();
        let strategy_id = order.strategy_id();

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Delay order submission until the venue is fully connected and the first AccountState has been received
  2. Check stream health and wait/retry after reconnects before resubmitting
  3. Verify API key permissions and (for US routing) that user data credentials are configured

Example fix

# before: order goes out before the user data stream is live
def on_start(self) -> None:
    self.submit_order(self.order_factory.market(...))

# after: gate on first account state (stream active)
def on_start(self) -> None:
    self._venue_ready = False
    self.request_account_state()

def on_account_state(self, event) -> None:
    if not self._venue_ready:
        self._venue_ready = True
        self.submit_order(self.order_factory.market(...))
Defensive patterns

Strategy: retry

Validate before calling

# gate first submission on the first account state (user data stream live)
def on_start(self) -> None:
    self._venue_ready = False
    self.request_account_state()

def on_account_state(self, event) -> None:
    self._venue_ready = True

def _submit_when_ready(self, order):
    if not self._venue_ready:
        self.clock.set_timer(...)  # retry shortly
        return
    self.submit_order(order)

Try / catch

match client.submit_order(cmd) {
    Err(e) if e.to_string().contains("user data stream is not active") => {
        // stream not up yet or reconnecting: back off and retry
        retry_after_backoff(cmd);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling submit_order/submit_order_list before the WS session's logon + userDataStream.subscribe completes; after the stream drops (listen-key expiry, disconnect) and before reconnect finishes; missing Binance US credentials for the user data stream.

Common situations: A strategy submitting orders in on_start before the venue finishes connecting; trading right after a network blip that killed the user data stream; API keys without the required permissions so the stream never comes up.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/89d43be0f726976a. Report an issue: GitHub.