nautechsystems/nautilus_trader · critical
Failed to set spread quote vega pricing timeout
Error message
Failed to set spread quote vega pricing timeout
What it means
After computing the vega pricing timeout alert time, the aggregator arms it with `LiveClock::set_time_alert_ns` and `.expect`s success. An Err means the clock could not register the alert (internal clock error or lifecycle problem), so the vega pricing timeout would never fire and quotes could hang waiting for stale greeks.
Source
Thrown at crates/data/src/aggregation.rs:2432
};
let callback = TimeEventCallback::RustLocal(Rc::new(move |_event: TimeEvent| {
if let Some(agg) = aggregator_weak.upgrade() {
agg.borrow_mut().clear_vega_pricing_timeout();
}
}));
let timeout = DurationNanos::try_from_secs(self.vega_pricing_timeout_seconds)
.expect("vega pricing timeout exceeds the nanosecond range");
let alert_time = self.clock.borrow().timestamp_ns() + timeout;
self.clock
.borrow_mut()
.set_time_alert_ns(
&self.vega_pricing_timeout_timer_name,
alert_time,
Some(callback),
Some(true),
)
.expect("Failed to set spread quote vega pricing timeout");
}
fn create_futures_spread_prices(&self) -> (f64, f64) {
let mut raw_ask = 0.0_f64;
let mut raw_bid = 0.0_f64;
for i in 0..self.leg_ids.len() {
let r = self.ratios[i] as f64;
if self.ratios[i] >= 0 {
raw_ask += r * self.ask_prices[i];
raw_bid += r * self.bid_prices[i];
} else {
raw_ask += r * self.bid_prices[i];
raw_bid += r * self.ask_prices[i];
}
}
(raw_bid, raw_ask)
}View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the aggregator cancels its vega timeout alert on stop and uses a unique timer name per instance/instrument
- Verify shutdown ordering: disarm alerts before clock teardown
- Log the underlying `set_time_alert_ns` error (replace expect with match/log) to pinpoint the cause
- If triggered by an invalid alert_time, fix the timeout seconds config (see the duration overflow error)
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: ensure prior alert cancelled before re-arming assert!(alerts_cleared.contains(&agg.vega_pricing_timeout_timer_name()), "vega timeout alert still armed");
Try / catch
let result = std::panic::catch_unwind(|| agg.arm_vega_pricing_timeout());
if result.is_err() { log::error!("failed to arm vega pricing timeout alert"); } Prevention
- Cancel the vega timeout alert in the aggregator's stop path
- Use unique timer names per aggregator instance
- Order shutdown: disarm alerts, then tear down the clock
When it happens
Trigger: Arming the `vega_pricing_timeout_timer_name` alert during spread quote initialization in live mode when the clock returns Err — duplicate alert name, clock already shut down, or a timer-name collision from restarting the aggregator without cleanup.
Common situations: Restarting a spread subscription without the previous alert being cancelled (name collision); teardown/shutdown races; misconfigured timeout producing an alert_time the clock rejects.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- timer event sender was unset for Rust callback system
- Callback should exist
- Failed to set spread quote timer
- Event '{}' should have associated handler
- timer queue peeked Some but pop returned None
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/431d87eadae377c3.
Report an issue: GitHub.