{"record":{"id":"252ee441be4754ed","repo":"nautechsystems/nautilus_trader","slug":"field-exceeds-the-maximum-backoff-duration","errorCode":null,"errorMessage":"{field} exceeds the maximum backoff duration","messagePattern":"(.+?) exceeds the maximum backoff duration","errorType":"validation","errorClass":"TransportError::Io(std::io::Error)","httpStatus":null,"severity":"error","filePath":"crates/network/src/websocket/client.rs","lineNumber":963,"sourceCode":"        })\n    } else {\n        Ok(RetryConfig {\n            max_retries: 0,\n            initial_delay_ms: 1,\n            max_delay_ms: 1,\n            backoff_factor: 1.0,\n            jitter_ms: 0,\n            operation_timeout_ms: None,\n            immediate_first: false,\n            max_elapsed_ms: None,\n        })\n    }\n}\n\nfn duration_to_millis(field: &str, duration: Duration) -> Result<u64, TransportError> {\n    let nanoseconds = duration.as_nanos();\n    if nanoseconds > u128::from(u64::MAX) {\n        return Err(TransportError::Io(std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            format!(\"{field} exceeds the maximum backoff duration\"),\n        )));\n    }\n\n    let milliseconds = nanoseconds\n        .div_ceil(1_000_000)\n        .min(u128::from(u64::MAX / 1_000_000));\n    u64::try_from(milliseconds).map_err(|_| {\n        TransportError::Io(std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            format!(\"{field} exceeds the maximum backoff duration\"),\n        ))\n    })\n}\n\nasync fn await_initial_connect_attempt<F, T>(\n    cancellation_token: &CancellationToken,","sourceCodeStart":945,"sourceCodeEnd":981,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/network/src/websocket/client.rs#L945-L981","documentation":"Retry backoff durations are converted to milliseconds (u64) for scheduling. If the duration's nanosecond value overflows `u64::MAX` (about 584 years), `duration_to_millis` rejects it with `InvalidInput`, naming the offending field, because such a duration cannot be represented for the timer.","triggerScenarios":"Constructing `RetryConfig` with a backoff field (e.g. `max_backoff`/initial backoff) computed to an astronomically large `Duration` — typically from a bad multiplication, a u128/u64 mixup, or a parsed value without bounds.","commonSituations":"Programmatic backoff generation (exponential growth without cap) or deserializing durations from configs with absurd numeric values.","solutions":["Cap the backoff field to a sane maximum (e.g. `Duration::from_secs(3600)`).","Audit the arithmetic that produces the duration for overflow or wrong units.","Clamp before constructing RetryConfig, mirroring the library's `min(u64::MAX / 1_000_000)` ms bound."],"exampleFix":"// before\nlet backoff = Duration::from_secs(initial).checked_mul(2u32.pow(n))?;\n// after\nlet backoff = Duration::from_secs(initial).checked_mul(2u32.pow(n))?.min(Duration::from_secs(3600));","handlingStrategy":"validation","validationCode":"fn cap_backoff(d: Duration, max: Duration) -> Duration {\n    if d > max { max } else { d }\n}\nlet retry = RetryConfig { max_backoff: cap_backoff(computed, Duration::from_secs(3600)), .. };","typeGuard":null,"tryCatchPattern":"match RetryConfig::new(initial, factor, max_backoff) {\n    Err(e) if e.to_string().contains(\"exceeds the maximum backoff duration\") => {\n        eprintln!(\"backoff duration overflow; capping to 1h\");\n        RetryConfig::new(initial, factor, Duration::from_secs(3600))?\n    }\n    other => other?,\n}","preventionTips":["Always cap exponential backoff growth with a maximum duration.","Check units when converting config numbers into Durations.","Use checked arithmetic (checked_mul) when scaling durations."],"tags":["rust","validation","duration","overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}