nautechsystems/nautilus_trader · error

Failed to restore actor {actor_id} state: {e:#}

Error message

Failed to restore actor {actor_id} state: {e:#}

What it means

Raised in `Trader::load_state` when an actor's registered `on_load` state-restoration callback itself returns an error. The state was successfully read from the cache, but the actor rejected restoring it (invalid/ incompatible payload), so state recovery aborts with this message.

Source

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

            (trader.cache.clone(), actor_callbacks, strategy_callbacks)
        };

        if !cache.borrow().has_backing() {
            return Ok(());
        }

        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:#}")
            })?;
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped `{e:#}` to see why the actor rejected the state and fix the deserialization/schema mismatch
  2. Ensure the same actor implementation and state schema that saved the state also restores it, or add a migration in the load callback
  3. Clear the actor's stale persisted state in the cache if it is no longer compatible, and re-run to save fresh state
  4. Pin/cache-compatible library versions across node restarts
Defensive patterns

Strategy: try-catch

Validate before calling

// verify state round-trips before restart
let state = cache.load_actor_state(&actor_id)?;
actor.test_restore(state.clone())?;

Try / catch

do {
    system.start_with_recovery()
} catch e if e.contains("Failed to restore actor") => {
    // clear the incompatible persisted state or migrate schema, then restart
}

Prevention

When it happens

Trigger: Calling trader start with state recovery enabled; the cache returns a non-empty `PersistedComponentState` for an actor, and the actor's `load` callback errors — e.g. the payload was saved by a different actor type/version or fails deserialization into the actor's internal state type.

Common situations: Upgrading nautilus and restarting with state persisted by the previous version; changing an actor's saved-state struct fields without a migration; pointing the node at a cache containing state from a different strategy/actor configuration.

Related errors


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