nautechsystems/nautilus_trader · error · anyhow::Error

Timeout waiting for account {account_id} to be registered af

Error message

Timeout waiting for account {account_id} to be registered after {timeout_secs}s

What it means

During connect, the execution client spawns a query_account task (request_account_state -> account state event) and then polls the shared cache every 10ms for the account_id to appear, up to timeout_secs. This bail means no AccountState for that exact account_id was processed in time: the WebSocket/HTTP flow that publishes account state never delivered it. Orders cannot be accepted before the account exists in the cache, so startup aborts.

Source

Thrown at crates/adapters/architect_ax/src/execution.rs:404

        if self.core.cache().account(&account_id).is_some() {
            log::info!("Account {account_id} registered");
            return Ok(());
        }

        let start = Instant::now();
        let timeout = Duration::from_secs_f64(timeout_secs);
        let interval = Duration::from_millis(10);

        loop {
            tokio::time::sleep(interval).await;

            if self.core.cache().account(&account_id).is_some() {
                log::info!("Account {account_id} registered");
                return Ok(());
            }

            if start.elapsed() >= timeout {
                anyhow::bail!(
                    "Timeout waiting for account {account_id} to be registered after {timeout_secs}s"
                );
            }
        }
    }
}

#[async_trait(?Send)]
impl ExecutionClient for AxExecutionClient {
    fn is_connected(&self) -> bool {
        self.core.is_connected()
    }

    fn client_id(&self) -> ClientId {
        self.core.client_id
    }

    fn account_id(&self) -> AccountId {

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Raise the account registration timeout in the exec config and retry connect
  2. Check logs just before the bail for a failed query_account or WS error and fix that first (credentials, network, ws_public_url)
  3. Confirm the whoami account for these credentials matches the account being awaited (account id mismatch = never registers)
  4. If the WS is the problem, verify ws_public_url/heartbeat settings and proxy reachability

Example fix

// before
let config = AxExecClientConfig::builder()
    .timeout_account_registration_secs(5.0) // too tight
    .build()?;
// after
let config = AxExecClientConfig::builder()
    .timeout_account_registration_secs(30.0)
    .build()?;
Defensive patterns

Strategy: retry

Validate before calling

// Before starting the engine: confirm the account exists for these creds
let whoami = raw_client.get_whoami().await?;
ensure!(!whoami.accounts.is_empty(), "key has no accounts");

Try / catch

// connect() returned Err(timeout): inspect cause, then one full reconnect
match exec_connect_result {
    Err(e) if e.to_string().contains("Timeout waiting for account") => {
        log::warn!("account registration timed out; reconnecting with longer timeout");
        increase_timeout_and_reconnect()?; // full WS + account-state retry
    }
    r => r,
}

Prevention

When it happens

Trigger: The account_id resolved at client construction (from whoami) differs from what the account-state stream reports; the AX WebSocket is not connected or its subscription failed; request_account_state itself errored (check for a query_account failure in logs); timeout_secs configured too small for a slow first snapshot.

Common situations: API key whose account set changed on the venue after startup; WS endpoint blocked/down (proxy, heartbeat timeouts); heavily loaded engine where first event processing exceeds the configured timeout; custom timeout_secs lowered during tuning.

Understand the failure class

Related errors


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