nautechsystems/nautilus_trader · error
{e}; failed to roll back external order claims for {strategy
Error message
{e}; failed to roll back external order claims for {strategy_id}: {rollback_error} What it means
In `add_strategy`, when creating the exec engine fails, the node tries to roll back external order claims registered for the strategy's instrument IDs. If that rollback also fails, the original error is augmented with the rollback failure via `anyhow::bail!` so both causes are visible. This preserves the original failure context while surfacing that cleanup could not complete, meaning external order claims may be left dangling.
Source
Thrown at crates/live/src/node/mod.rs:2732
self.register_external_order_claims(strategy_id, &instrument_ids)?;
}
let mut exec_engine = match oms_type
.map(|_| {
self.kernel
.exec_engine
.try_borrow_mut()
.map_err(|e| anyhow::anyhow!("Cannot register OMS type: {e}"))
})
.transpose()
{
Ok(exec_engine) => exec_engine,
Err(e) => {
if !instrument_ids.is_empty()
&& let Err(rollback_error) =
self.rollback_external_order_claims(strategy_id, &instrument_ids)
{
anyhow::bail!(
"{e}; failed to roll back external order claims for {strategy_id}: {rollback_error}"
);
}
return Err(e);
}
};
if let Err(add_error) = self.kernel.trader.borrow_mut().add_strategy(strategy) {
drop(exec_engine);
if !instrument_ids.is_empty()
&& let Err(rollback_error) =
self.rollback_external_order_claims(strategy_id, &instrument_ids)
{
anyhow::bail!(
"Failed to add strategy {strategy_id}: {add_error}; failed to roll back external order claims: {rollback_error}"
);
}View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the root cause reported in the leading `{e}` part of the message (exec engine creation failure) first.
- Inspect why rollback failed (trailing `{rollback_error}`): verify the cache/backing store used by external order claims is reachable and consistent.
- Restart the node to clear any stale in-memory claim state, then re-add the strategy.
- Check that instrument_ids passed to add_strategy are valid and that no concurrent add_strategy call is mutating the same claims.
Example fix
// before: rollback failure is opaque
anyhow::bail!("{e}; failed to roll back external order claims for {strategy_id}: {rollback_error}");
// after: caller ensures node is idle and cache healthy before adding
assert_eq!(node.state(), NodeState::Idle);
node.connect_cache()?; // ensure backing cache reachable
node.add_strategy(strategy)?; Defensive patterns
Strategy: try-catch
Validate before calling
if node.state() != NodeState::Idle {
anyhow::bail!("node must be idle before add_strategy");
} Type guard
fn can_add(node: &LiveNode) -> bool { node.state() == NodeState::Idle } Try / catch
match node.add_strategy(strategy) {
Err(e) if e.to_string().contains("failed to roll back external order claims") => {
// both engine creation and rollback failed: inspect inner rollback_error, restart node
}
Err(e) => return Err(e),
Ok(_) => {}
} Prevention
- Ensure the cache/backing store is connected before adding strategies.
- Keep add_strategy calls on a single thread to avoid claim races.
- Monitor node state before mutating node configuration.
When it happens
Trigger: Calling `add_strategy` where exec engine creation returns `Err(e)` AND `instrument_ids` is non-empty AND `rollback_external_order_claims` itself returns `Err(rollback_error)` (e.g. claim records missing, cache lock poisoned, or a persistence/redis failure during claim removal).
Common situations: A misconfigured strategy or unavailable data/exec client causes engine creation to fail, while the rollback path independently fails due to a broken cache/redis connection or the claims having already been partially removed by a previous failed attempt.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed to add strategy {strategy_id}: {add_error}; failed to
- {startup_err}; failed to finalize startup abort: {finalize_e
- Failed during trader startup: {start_err}; failed to stop pa
- Failed during trader startup: {start_err}; failed to finaliz
- Failed during trader startup: {start_err}; failed to stop pa
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b3802b03aed4c7c3.
Report an issue: GitHub.