nautechsystems/nautilus_trader · error

load channel closed: {e}

Error message

load channel closed: {e}

What it means

Like `load_state`, the generic `load` helper runs a blocking Redis operation on a worker thread and receives the result through an mpsc channel. This error means `blocking_recv(&rx)` failed with `RecvError`: the sender half was dropped without delivering a result, so the worker task died or was dropped before completing.

Source

Thrown at crates/infrastructure/src/redis/cache.rs:1407

                    let Some(value) = value else {
                        continue;
                    };

                    if let Some(clean_key) = key.strip_prefix(&prefix) {
                        general.insert(clean_key.to_string(), value);
                    }
                }

                Ok(general)
            }
            .await;

            if let Err(e) = tx.send(result) {
                log::error!("Failed to send general load result: {e:?}");
            }
        });

        blocking_recv(&rx).map_err(|e| anyhow::anyhow!("load channel closed: {e}"))?
    }

    async fn load_currencies(&self) -> anyhow::Result<AHashMap<Ustr, Currency>> {
        DatabaseQueries::load_currencies(
            &self.database.con,
            &self.database.trader_key,
            self.encoding(),
        )
        .await
    }

    async fn load_instruments(&self) -> anyhow::Result<AHashMap<InstrumentId, InstrumentAny>> {
        DatabaseQueries::load_instruments(
            &self.database.con,
            &self.database.trader_key,
            self.encoding(),
        )
        .await

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect logs immediately preceding this error for a panic or 'Failed to send general load result' message to find the true failure
  2. Retry the load after confirming the Redis connection is healthy
  3. Check that payloads in Redis match the expected encoding/schema
  4. Harden the worker task to return errors through the channel rather than panicking or only logging
Defensive patterns

Strategy: retry

Try / catch

// Rust
match cache.load(...).await {
    Ok(v) => v,
    Err(e) if e.to_string().contains("load channel closed") => {
        log::warn!("load worker died ({e:#}); retrying");
        cache.load(...).await
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any cache load operation routed through this helper (e.g. `load_currencies`, `load_instruments`) where the spawned task panics or is cancelled before `tx.send(result)` executes.

Common situations: Panics inside deserialization of Redis payloads; runtime teardown while a load is in flight; resource exhaustion (OOM) killing the worker thread.

Related errors


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