{"record":{"id":"06988d4d694045c3","repo":"clockworklabs/SpacetimeDB","slug":"invalid-seek-to-a-negative-or-overflowing-position","errorCode":null,"errorMessage":"invalid seek to a negative or overflowing position","messagePattern":"invalid seek to a negative or overflowing position","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/commitlog/src/repo/mem/segment.rs","lineNumber":167,"sourceCode":"    }\n}\n\nimpl io::Seek for Segment {\n    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {\n        let (base_pos, offset) = match pos {\n            io::SeekFrom::Start(n) => {\n                self.pos = n;\n                return Ok(n);\n            }\n            io::SeekFrom::End(n) => (self.len() as u64, n),\n            io::SeekFrom::Current(n) => (self.pos, n),\n        };\n        match base_pos.checked_add_signed(offset) {\n            Some(n) => {\n                self.pos = n;\n                Ok(n)\n            }\n            None => Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"invalid seek to a negative or overflowing position\",\n            )),\n        }\n    }\n}\n\nimpl SegmentLen for Segment {\n    fn segment_len(&mut self) -> io::Result<u64> {\n        Ok(self.len() as _)\n    }\n}\n\nimpl FileLike for Segment {\n    fn fsync(&mut self) -> io::Result<()> {\n        Ok(())\n    }\n","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/commitlog/src/repo/mem/segment.rs#L149-L185","documentation":"The in-memory Segment implements io::Seek with std::io::Cursor semantics. SeekFrom::Start is always allowed (even past the end), but a relative seek (SeekFrom::Current or SeekFrom::End) whose signed offset would move the position below zero, or overflow u64, fails base_pos.checked_add_signed(offset) and returns io::ErrorKind::InvalidInput with this message.","triggerScenarios":"seek(SeekFrom::End(-n)) with n greater than the segment length; seek(SeekFrom::Current(-n)) with n greater than the current position; an offset computed via i64 subtraction that underflows (e.g. pos - extra as i64 when extra > pos).","commonSituations":"Rewind-by-N logic after reading variable-length records; subtracting a header/checksum size from a position that is smaller than it; porting seek code that assumed clamping instead of erroring.","solutions":["Compute the absolute target first (stream_position()/len() + checked_add_signed) and clamp to 0 before issuing SeekFrom::Start","Guard relative seeks: only seek End(-n)/Current(-n) when n <= len()/stream_position()","Use u64 arithmetic and SeekFrom::Start instead of signed Current/End offsets"],"exampleFix":"// before\nsegment.seek(io::SeekFrom::Current(-(header_len as i64)))?;\n\n// after\nlet pos = segment.stream_position()?;\nlet target = pos.saturating_sub(header_len as u64);\nsegment.seek(io::SeekFrom::Start(target))?;","handlingStrategy":"validation","validationCode":"let pos = segment.stream_position()?;\nlet len = segment.seek(io::SeekFrom::End(0))?;\n// compute the target absolutely, clamped to the segment bounds\nlet target = (pos as i64 + delta).clamp(0, len as i64) as u64;\nsegment.seek(io::SeekFrom::Start(target))?;","typeGuard":"fn is_invalid_seek(err: &io::Error) -> bool {\n    err.kind() == io::ErrorKind::InvalidInput\n        && err.to_string().contains(\"negative or overflowing position\")\n}","tryCatchPattern":"let new_pos = match segment.seek(rel) {\n    Ok(p) => p,\n    Err(e) if is_invalid_seek(&e) => {\n        // recover by clamping to start\n        segment.seek(io::SeekFrom::Start(0))?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Prefer SeekFrom::Start with absolute u64 positions computed via checked/saturating arithmetic","Never subtract first in i64 when the subtrahend may exceed the position; use u64 saturating_sub","For End-relative seeks, check len() >= n before issuing seek(End(-n))"],"tags":["rust","commitlog","in-memory","seek","invalid-input"],"backgroundTag":"invalid-seek-offset","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}