nautechsystems/nautilus_trader · error
Cumulative fill went backwards: acc_fill_sz='{acc_fill_sz}'
Error message
Cumulative fill went backwards: acc_fill_sz='{acc_fill_sz}' < previous_filled_qty={prev_qty} (possible stale data after reconnect) What it means
Regular order fill parsing also treats acc_fill_sz as a monotonically increasing cumulative total. An update whose cumulative value is below the previously observed filled quantity is rejected as stale data (commonly replayed after reconnect) rather than applied, protecting order state from regression.
Source
Thrown at crates/adapters/okx/src/websocket/parse.rs:2118
)
})?;
// OKX provides fillSz (incremental fill) or accFillSz (cumulative total)
// If fillSz is provided, use it directly as the incremental fill quantity
let last_qty = if !msg.fill_sz.is_empty() && msg.fill_sz != "0" {
parse_quantity(&msg.fill_sz, size_precision)
.map_err(|e| anyhow::anyhow!("Failed to parse fill_sz='{}': {e}", msg.fill_sz,))?
} else if let Some(ref acc_fill_sz) = msg.acc_fill_sz {
// If fillSz is missing but accFillSz is available, calculate incremental fill
if !acc_fill_sz.is_empty() && acc_fill_sz != "0" {
let current_filled = parse_quantity(acc_fill_sz, size_precision).map_err(|e| {
anyhow::anyhow!("Failed to parse acc_fill_sz='{acc_fill_sz}': {e}",)
})?;
// Calculate incremental fill as: current_total - previous_total
if let Some(prev_qty) = previous_filled_qty {
if current_filled < prev_qty {
anyhow::bail!(
"Cumulative fill went backwards: acc_fill_sz='{acc_fill_sz}' < previous_filled_qty={prev_qty} \
(possible stale data after reconnect)"
);
}
let incremental = current_filled - prev_qty;
if incremental.is_zero() {
log::debug!(
"Skipping duplicate fill: acc_fill_sz='{acc_fill_sz}' unchanged from previous={prev_qty}"
);
return Ok(None);
}
incremental
} else {
// First fill, use accumulated as incremental
current_filled
}
} else {
anyhow::bail!(View on GitHub (pinned to 18893faf8b)
Solutions
- Check for duplicate/overlapping subscriptions and ensure the reconnect handler re-syncs state via REST before resuming the stream
- Catch this error and drop the stale update if out-of-order delivery is expected in your deployment
- Track a sequence/timestamp per order and ignore updates older than the last applied one
Example fix
// before
let report = parse_fill_report(&msg, instrument, Some(prev_qty), ...)?; // bails on regression
// after
match parse_fill_report(&msg, instrument, Some(prev_qty), ...) {
Ok(r) => handle(r),
Err(e) if e.to_string().contains("went backwards") => tracing::warn!("stale fill ignored"),
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
if let (Some(prev), Some(acc)) = (previous_filled_qty, &msg.acc_fill_sz) {
let cur: u64 = acc.parse().unwrap_or(0);
if cur < prev.raw() { /* stale: drop or resync via REST */ }
} Try / catch
match parse_fill_report(&msg, instrument, prev_qty, ...) {
Ok(r) => handle(r),
Err(e) if e.to_string().contains("went backwards") => tracing::warn!("stale fill dropped: {e}"),
Err(e) => return Err(e),
} Prevention
- Resync filled quantities from REST after every WebSocket reconnect
- Avoid duplicate orders-channel subscriptions
- Track last-seen update timestamps per instrument/order
When it happens
Trigger: An orders-channel update with acc_fill_sz less than the previously tracked filled quantity for the same order — usually an out-of-order or replayed message after a WebSocket reconnect.
Common situations: Reconnect replaying buffered messages; duplicate subscriptions delivering old snapshots; clock/sequence skew between REST snapshot and WS stream.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cumulative spread fill went backwards: acc_fill_sz='{}' < pr
- Previous WebSocket handler failed: {e}
- Invalid `BarSpecification` for channel, was {bar_spec}
- errors.join("; ")
- Timeout waiting for account {account_id} to be registered af
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dc6863e69d27c55b.
Report an issue: GitHub.