nautechsystems/nautilus_trader · 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

The Derive exec client's await_account_registered polls the cache for the account state after connecting, and bails if the account is not registered within timeout_secs. It indicates the WS/HTTP auth or account-state handshake never produced a registered AccountState. This is a connect-time failure, so the client cannot execute.

Source

Thrown at crates/adapters/derive/src/execution.rs:401

        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"
                );
            }
        }
    }

    /// Reverses the partial state `connect()` set up before the failing step:
    /// cancels the shared cancellation token, aborts the WS dispatch task,
    /// and closes the WS client. Used when initial account state cannot be
    /// loaded so that the next `connect()` call starts from a clean slate.
    async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {
        self.cancellation_token.cancel();
        self.abort_session_tasks();
        self.abort_pending_tasks();

        if let Err(e) = self.ws_client.disconnect().await {
            self.shutdown_errors
                .push(format!("Derive WebSocket shutdown failed: {e}"));

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify Derive API credentials (wallet address and private key) are correct and authorized
  2. Increase the account-registration timeout in the exec client config
  3. Check logs for WS auth/subscription errors immediately preceding the timeout
  4. Confirm network/proxy connectivity to Derive WS endpoints and retry

Example fix

// before
DeriveExecClientConfig { account_registered_timeout_secs: 2, .. }
// after
DeriveExecClientConfig { account_registered_timeout_secs: 30, .. }
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check credentials present before connect
if config.private_key.is_empty() || config.wallet_address.is_empty() {
    return Err("Derive credentials missing".into());
}

Try / catch

match client.connect().await {
    Err(e) if e.to_string().contains("Timeout waiting for account") => {
        log::error!("Derive account never registered; check creds/WS auth: {e}");
        // retry with larger timeout
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling connect() on DeriveExecClient when the account never appears in the cache within the configured timeout — e.g. WS auth failed, subscription to account state silently stalled, or the timeout is set too low for a slow network.

Common situations: Wrong or expired Derive API credentials so no account state ever arrives; very short account_registered_timeout_secs in a slow/remote environment; WS connected but account channel subscription failing silently.

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