nautechsystems/nautilus_trader · error

Derive execution startup teardown failed: {teardown_error}

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.

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)

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.