nautechsystems/nautilus_trader · error
load_index_order_client channel closed: {e}
Error message
load_index_order_client channel closed: {e} What it means
Loads the (client_order_id → client_id) index from Redis through the same worker-thread + mpsc pattern. This error means `blocking_recv(&rx)` got `RecvError` because the sending task terminated without sending — a panic, drop, or early exit in the worker.
Source
Thrown at crates/infrastructure/src/redis/cache.rs:1504
blocking_recv(&rx)
.map_err(|e| anyhow::anyhow!("load_index_order_position channel closed: {e}"))?
}
fn load_index_order_client(&self) -> anyhow::Result<AHashMap<ClientOrderId, ClientId>> {
let con = self.database.con.clone();
let trader_key = self.database.trader_key.clone();
let (tx, rx) = mpsc::channel();
get_runtime().spawn(async move {
let result = DatabaseQueries::load_index_order_client(&con, &trader_key).await;
if let Err(e) = tx.send(result) {
log::error!("Failed to send load_index_order_client result: {e:?}");
}
});
blocking_recv(&rx)
.map_err(|e| anyhow::anyhow!("load_index_order_client channel closed: {e}"))?
}
async fn load_currency(&self, code: &Ustr) -> anyhow::Result<Option<Currency>> {
DatabaseQueries::load_currency(
&self.database.con,
&self.database.trader_key,
code,
self.encoding(),
)
.await
}
async fn load_instrument(
&self,
instrument_id: &InstrumentId,
) -> anyhow::Result<Option<InstrumentAny>> {
DatabaseQueries::load_instrument(
&self.database.con,View on GitHub (pinned to 18893faf8b)
Solutions
- Check logs right before the error for the real cause (panic trace or send-failure log)
- Verify the index_order_client keys in Redis deserialize under the current encoding; delete/rewrite bad entries
- Retry the load once the Redis connection is stable
- Propagate worker errors through the channel to avoid this opaque RecvError wrapper
Defensive patterns
Strategy: retry
Try / catch
// Rust
match cache.load_index_order_client() {
Ok(index) => index,
Err(e) if e.to_string().contains("channel closed") => {
log::warn!("retrying index_order_client load after channel close: {e:#}");
cache.load_index_order_client()
}
Err(e) => return Err(e),
} Prevention
- Inspect preceding logs for the worker's real failure (panic or send failure)
- Ensure index entries in Redis match the current schema/encoding
- Do not issue loads during runtime teardown
- Harden the loader task to send Err results instead of dying silently
When it happens
Trigger: Calling the client-order index load during cache load when the spawned task fails before `tx.send(result)` (deserialization panic on index entries, connection drop inside the task, task cancellation).
Common situations: Corrupt or schema-changed index data in Redis; runtime shutdown during startup; incompatible data written by an older nautilus version.
Related errors
- load_index_order_position channel closed: {e}
- load_state channel closed: {e}
- load channel closed: {e}
- Failed to send SetClient command: {e}
- Failed to send to channel: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/78c2768f12f82397.
Report an issue: GitHub.