nautechsystems/nautilus_trader · error

Failed to load strategy {strategy_id} state: {e:#}

Error message

Failed to load strategy {strategy_id} state: {e:#}

What it means

Raised in `Trader::load_state` when the cache fails to load previously persisted state for a strategy (`cache.load_strategy_state`). The trader is restoring strategies after restart; a read error aborts the whole restore pass so strategies never start with silently missing state.

Source

Thrown at crates/system/src/trader.rs:1599

        for (actor_id, callbacks) in actor_callbacks {
            let state = cache
                .borrow()
                .load_actor_state(&actor_id)
                .map_err(|e| anyhow::anyhow!("Failed to load actor {actor_id} state: {e:#}"))?;
            let Some(state) = state.filter(|state| !state.is_empty()) else {
                continue;
            };

            (callbacks.load)(actor_id.inner(), state)
                .map_err(|e| anyhow::anyhow!("Failed to restore actor {actor_id} state: {e:#}"))?;
        }

        for (strategy_id, callbacks) in strategy_callbacks {
            let state = cache
                .borrow()
                .load_strategy_state(&strategy_id)
                .map_err(|e| {
                    anyhow::anyhow!("Failed to load strategy {strategy_id} state: {e:#}")
                })?;
            let Some(state) = state.filter(|state| !state.is_empty()) else {
                continue;
            };

            (callbacks.load)(strategy_id.inner(), state).map_err(|e| {
                anyhow::anyhow!("Failed to restore strategy {strategy_id} state: {e:#}")
            })?;
        }

        Ok(())
    }

    /// Saves actor and strategy state in registration order.
    ///
    /// Empty state is persisted, while a cache without database backing does not invoke
    /// component callbacks. All callbacks and updates receive an attempt before errors return.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the wrapped `{e:#}` chain for the root cause and restore backing-store connectivity/credentials
  2. Verify cache backend config in the system config matches the store that wrote the state
  3. If the persisted strategy state is from an incompatible version, clear the stale key and restart (strategy starts with empty state)
  4. Re-save state from a run of the compatible version before restarting the upgraded node
Defensive patterns

Strategy: retry

Validate before calling

// confirm the strategy state key exists and is readable before restart
match cache_backend.get(format!("strategy_state:{strategy_id}")) {
    Ok(Some(_)) => {},
    other => handle(other),
}

Try / catch

match system.start_with_recovery() {
    Err(e) if e.to_string().contains("Failed to load strategy") => {
        // restore backend connectivity or clear the stale key, then retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling trader start with state recovery enabled when `load_strategy_state(strategy_id)` errors — backing-store connection failure, corrupted/expired key, or serialization error for that strategy's state key.

Common situations: Restarting a live node against a Redis cache that is down, has rotated credentials, or whose keys were written under a different schema/version; the strategy's state key was manually deleted or expired.

Related errors


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