nautechsystems/nautilus_trader · error
Failed to register Betfair race fatal task: {e}
Error message
Failed to register Betfair race fatal task: {e} What it means
Registering the race stream's fatal-error monitoring task failed; the underlying error `{e}` is re-wrapped. This task watches the race stream for fatal conditions and triggers reconnection/shutdown; without it, a dead race stream would go undetected, so connect aborts.
Source
Thrown at crates/adapters/betfair/src/data.rs:883
.push(BetfairStreamShutdown::Auxiliary(Arc::clone(&race_client)));
let race_socket_control = self.race_socket_control.as_ref().map(Arc::clone);
self.session_tasks
.spawn(async move {
if race_fatal_rx.recv().await.is_some() {
log::error!(
"Betfair race stream permanently disabled due to fatal error"
);
race_client.close().await;
if let Some(control) = race_socket_control {
control.deregister();
}
}
})
.map_err(|e| {
anyhow::anyhow!("Failed to register Betfair race fatal task: {e}")
})?;
log::debug!("Betfair race stream connected");
}
Err(e) => {
log::warn!("Betfair race stream connect failed: {e}");
if let Some(control) = &self.race_socket_control {
control.deregister();
}
self.race_stream_client = None;
}
}
}
if self.config.subscribe_cricket_data {
let cricket_config = BetfairStreamConfig {
host: BETFAIR_RACE_STREAM_HOST.to_string(),View on GitHub (pinned to 18893faf8b)
Solutions
- Read the inner `{e}` for the exact registration failure (likely TaskGroup spawn error)
- Ensure connect is not racing disconnect/shutdown on the same client
- Retry connect so the race stream and its fatal watcher are registered in the same generation
- Note: race stream connect failure itself is only a warning; only the fatal-task registration aborts — check whether the race stream endpoint actually connected
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure no shutdown in progress before connect
if client.is_shutting_down() { return Err(anyhow::anyhow!("connect during shutdown")); } Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("Failed to register Betfair race fatal task") => {
log::error!("race fatal watcher not registered: {e:#}");
// retry connect; ensure disconnect() isn't running concurrently
}
other => other,
} Prevention
- Never interleave connect and disconnect calls concurrently
- Complete prior teardowns before reconnecting
- Treat race-stream connect warnings separately from registration failures
- Retry connect to re-register the fatal watcher in a fresh generation
When it happens
Trigger: connect() -> after spawning the race stream task, .map_err wraps the registration (spawn onto a task group / stream shutdown registry) error. Typically occurs when the target TaskGroup is not open (shutdown in progress) or the spawn fails because the group was closed concurrently.
Common situations: Connect racing a disconnect that closed the task group; reconnect loops where the group generation ended before registration; internal spawn failure.
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 register Betfair cricket fatal task: {e}
- Failed to start AX execution session generation: {e}
- Failed to finish Betfair data session tasks: {e}
- Failed to start Betfair data session tasks: {e}
- Failed to start Betfair data command tasks: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/51667dc0fdd9ef15.
Report an issue: GitHub.