nautechsystems/nautilus_trader · error

Derive execution startup teardown failed

Error message

Derive execution startup teardown failed: {teardown_error}

What it means

This error is returned by Derive execution client connect() when subscribing to the private WebSocket channels (orders, balances) fails AND the partial-connect teardown also fails. The original subscription error is preserved as the source, with the teardown error appended, telling the caller the startup failed and cleanup could not complete either — the client may be left in a partially-connected state.

Solutions

  1. Check the chained source error for the original subscription failure cause (auth, network)
  2. Force-disconnect or recreate the ws_client since teardown failed and state may be inconsistent
  3. Verify Derive API credentials and subaccount_id are valid before connecting
  4. Retry connect() with a freshly constructed execution client
  5. Check Derive service status / network reachability if subscriptions time out
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate credentials and connectivity before subscribing
if !derive_credentials_valid(config) {
    return Err(anyhow!("invalid Derive credentials; refusing connect"));
}

Type guard

fn is_teardown_failure(err: &anyhow::Error) -> bool {
    err.to_string().contains("startup teardown failed")
}

Try / catch

match exec_client.connect().await {
    Err(e) if is_teardown_failure(&e) => {
        // subscribe AND teardown failed: client state unknown, recreate it
        let fresh = DeriveExecutionClient::new(config)?;
        fresh.connect().await
    }
    other => other,
}

Prevention

When it happens

Trigger: ws_client.subscribe_channels(channels) for the Derive private channels returns Err, then teardown_partial_connect().await also returns Err.

Common situations: Derive API auth failure (bad API credentials) causing subscription rejection, followed by a teardown that itself errors (broken WS state); network drop during startup; ws_client in an inconsistent state after the failed subscribe.

Related errors


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

Appendix: source

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

            if let Err(teardown_error) = self.teardown_partial_connect().await {
                return Err(e.context(format!(
                    "Derive execution startup teardown failed: {teardown_error}"
                )));
            }
            return Err(e);
        };

        let subaccount_id = self.credential.subaccount_id();
        let channels = vec![
            DeriveWsChannel::orders(subaccount_id),
            DeriveWsChannel::private_trades(subaccount_id),
            DeriveWsChannel::balances(subaccount_id),
        ];

        if let Err(e) = self.ws_client.subscribe_channels(channels).await {
            log::warn!("Derive private WS subscriptions failed: {e}; tearing down");
            if let Err(teardown_error) = self.teardown_partial_connect().await {
                return Err(anyhow::Error::new(e).context(format!(
                    "Derive execution startup teardown failed: {teardown_error}"
                )));
            }
            return Err(anyhow::Error::new(e).context("failed Derive private WS subscriptions"));
        }

        if let Err(e) = self.start_ws_dispatch(rx) {
            if let Err(teardown_error) = self.teardown_partial_connect().await {
                return Err(e.context(format!(
                    "Derive execution startup teardown failed: {teardown_error}"
                )));
            }
            return Err(e.context("failed to register Derive execution WebSocket dispatch task"));
        }

        // Fail-fast if the initial account snapshot cannot load: without it,
        // `await_account_registered` would block the full timeout window and
        // surface a misleading registration timeout. Tear down the WS we

View on GitHub (pinned to 18893faf8b)