{"record":{"id":"81344ad99e312c28","repo":"nautechsystems/nautilus_trader","slug":"venue-order-id-counter-exhausted","errorCode":null,"errorMessage":"Venue order ID counter exhausted","messagePattern":"Venue order ID counter exhausted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/matching_engine/ids_generator.rs","lineNumber":265,"sourceCode":"            ))\n        }\n    }\n\n    /// Generates a venue order ID.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the deterministic order counter is exhausted.\n    pub fn generate_venue_order_id(&mut self) -> VenueOrderId {\n        self.try_generate_venue_order_id()\n            .expect(\"Venue order ID counter exhausted\")\n    }\n\n    fn try_generate_venue_order_id(&mut self) -> anyhow::Result<VenueOrderId> {\n        self.order_count = self\n            .order_count\n            .checked_add(1)\n            .ok_or_else(|| anyhow::anyhow!(\"Venue order ID counter exhausted\"))?;\n\n        if self.use_random_ids {\n            Ok(VenueOrderId::new(UUID4::new().to_string()))\n        } else {\n            Ok(VenueOrderId::new(\n                format!(\"{}-{}-{}\", self.venue, self.raw_id, self.order_count).as_str(),\n            ))\n        }\n    }\n}\n\nfn fnv1a_trade_id_hash(venue: Venue, raw_id: u32, ts_init_ns: u64) -> u64 {\n    let mut hash: u64 = FNV_OFFSET_BASIS;\n\n    for bytes in [\n        venue.as_str().as_bytes(),\n        b\"\\x1f\",\n        &raw_id.to_le_bytes(),","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/matching_engine/ids_generator.rs#L247-L283","documentation":"The matching engine's venue order ID generator maintains an internal u64/i128-style counter used to build venue order IDs of the form {venue}-{raw_id}-{count}. When incrementing the counter with checked_add overflows the numeric type, generation fails with this error, preventing silent ID reuse or wraparound.","triggerScenarios":"Generating more venue order IDs in one matching engine's lifetime than the counter type can represent — practically only via extremely long-running simulations, exhaustive backtests, or a misconfigured raw_id base pushing the counter near its maximum.","commonSituations":"Very large-scale backtests or market-replay runs generating billions of orders; a custom use_random_ids=false setup with a near-max initial raw_id; long-lived live matching engine instances never restarted.","solutions":["Restart or recreate the matching engine to reset the order ID counter at a safe baseline.","Enable use_random_ids (UUID-based venue order IDs) so numeric counter capacity is irrelevant.","Reduce order volume per engine instance or shard the run across multiple engines with distinct raw_id values.","Upgrade to a build where the counter uses a wider integer type if your workload legitimately exceeds the current width."],"exampleFix":"// before: sequential IDs with huge volume, counter eventually overflows\nlet gen = OrderIdsGenerator::new(venue, raw_id, false /* use_random_ids */);\n// after: UUID-based IDs avoid counter exhaustion\nlet gen = OrderIdsGenerator::new(venue, raw_id, true /* use_random_ids */);","handlingStrategy":"validation","validationCode":"// estimate whether the run can exceed counter capacity before starting\nlet expected_orders: u128 = estimated_orders(run_config);\nassert!(expected_orders < i64::MAX as u128,\n    \"run would exhaust the venue order ID counter; use random IDs or shard\");","typeGuard":null,"tryCatchPattern":"match ids_generator.get_venue_order_id() {\n    Err(e) if e.to_string().contains(\"counter exhausted\") => {\n        log::error!(\"order ID space exhausted, restarting generator: {e}\");\n        ids_generator.reset(); // or switch to use_random_ids and retry once\n    }\n    other => other,\n}","preventionTips":["Prefer use_random_ids for very long-running or high-volume engines.","Assign distinct raw_id values when sharding across engines.","Restart engines between backtest runs instead of reusing one instance for billions of orders."],"tags":["matching-engine","integer-overflow","order-ids","checked-arithmetic"],"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"}