nautechsystems/nautilus_trader · error
Failed to terminate Lighter tasks: {}
Error message
Failed to terminate Lighter tasks: {} What it means
Aggregated shutdown-failure error from the Lighter execution client. finish_session_shutdown (invoked by connect on failure and by disconnect) drains shutdown_errors accumulated from finishing owned tasks (WS senders, writers, nonce manager, etc.); if any are present it bails with this message and the joined per-task errors. It signals the execution session's background tasks did not all terminate cleanly.
Source
Thrown at crates/adapters/lighter/src/execution.rs:479
)
.await;
if let Err(e) = self
.pending_tasks
.finish_shutdown(Duration::from_secs(1), DISCONNECT_TIMEOUT)
.await
{
self.shutdown_errors
.push(format!("client-owned tasks failed: {e}"));
}
let stale = self.dispatch.take_pending_sendtx();
warn_pending_sendtx_unknown(&stale, "session shutdown");
self.nonce_recovery_inflight.store(false, Ordering::Release);
if !self.shutdown_errors.is_empty() {
let errors = std::mem::take(&mut self.shutdown_errors);
anyhow::bail!("Failed to terminate Lighter tasks: {}", errors.join("; "));
}
Ok(())
}
async fn finish_owned_task(
slot: &mut TaskSlot<()>,
description: &str,
errors: &mut Vec<String>,
) {
let Some(outcome) = finish_task(slot, DISCONNECT_TIMEOUT, DISCONNECT_TIMEOUT).await else {
return;
};
match outcome {
TaskJoinOutcome::Completed(()) => {
log::debug!("Lighter {description} task completed");
}
TaskJoinOutcome::Aborted => {View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the joined error text after the prefix to identify which task failed and why.
- Retry disconnect(); teardown errors during an outage typically resolve once connectivity is restored and usually don't affect already-submitted orders.
- Check connectivity/proxy stability if this fires on every shutdown.
- If shutdown consistently reports errors on a healthy connection, capture the full message and file a bug with the task description listed in it.
Defensive patterns
Strategy: try-catch
Try / catch
match exec_client.disconnect().await {
Ok(()) => {}
Err(e) if e.to_string().starts_with("Failed to terminate Lighter tasks") => {
tracing::warn!("execution teardown errors: {e:#}");
// parse joined task errors; retry disconnect if network was down
}
Err(e) => return Err(e),
} Prevention
- Avoid disconnecting while orders are in flight; await order terminal states first.
- Retry disconnect after transient network failures.
- Log and inspect the joined task errors to find the failing background task.
When it happens
Trigger: Calling disconnect() on the Lighter execution client (or connect() aborting partway) while one or more owned tasks returned an error on completion - e.g. WS send channel already closed, writer task failed on a broken transport, or a task panicked.
Common situations: Disconnecting while an order submission is in flight and the writer task errors; network outage during teardown; repeated reconnect cycles leaving errored task handles; nonce manager task failing during shutdown.
Related errors
- {context}: {}
- failed to finish Binance Futures data command tasks: {e}
- Binance Futures data teardown failed: {}
- Bybit execution shutdown failed: {}
- errors.join("; ") (aggregated shutdown errors)
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5ee3ffa6fee5db68.
Report an issue: GitHub.