pola-rs/polars · error · std::io::Error
invalid seek to a negative or overflowing position
Error message
invalid seek to a negative or overflowing position
What it means
ChunkedBytesCursor::seek returns an io::Error of kind InvalidInput when the requested seek position (base position plus signed offset) is negative or overflows usize. The cursor cannot represent such a position, so the seek fails instead of wrapping. It surfaces as a standard std::io::Error, typically wrapped in a Polars error by higher layers.
Solutions
- Verify the file is not truncated or corrupted; re-download/regenerate the source file
- Check computed offsets before seeking (use checked arithmetic on offsets)
- Ensure SeekFrom::Start values fit within u64/usize bounds and Current/End offsets don't go negative
Example fix
// before let off = row_group_offset - computed_offset; // may underflow cursor.seek(SeekFrom::Current(off))?; // after let off = row_group_offset.checked_sub(computed_offset).ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "negative offset"))?; cursor.seek(SeekFrom::Current(off))?;
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: bounds-check before seeking
fn safe_seek(cursor: &mut ChunkedBytesCursor, pos: u64) -> std::io::Result<()> {
if pos > usize::MAX as u64 { return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "position out of range")); }
cursor.seek(std::io::SeekFrom::Start(pos))
} Type guard
fn seekable(pos: u64) -> bool { pos <= usize::MAX as u64 } Try / catch
match cursor.seek(SeekFrom::Current(off)) {
Ok(p) => { /* use p */ },
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => { /* negative/overflowing seek: recover or abort */ },
Err(e) => return Err(e.into()),
} Prevention
- Use checked arithmetic for all offset computations
- Validate file metadata offsets against actual file size before seeking
- Treat truncated/corrupt files as suspect when InvalidInput seeks occur
When it happens
Trigger: Calling Seek::seek with SeekFrom::Start larger than usize::MAX, a SeekFrom::Current/End offset that moves before position 0, or a target beyond usize addressable range on a ChunkedBytesCursor.
Common situations: Corrupted Parquet/IPC metadata containing out-of-range offsets; code computing byte offsets with underflow; reading truncated files where stored offsets exceed actual buffer length combined with End-relative seeks.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/e11bf3f3ad98348c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-utils/src/chunked_bytes_cursor.rs:129
impl<'a, T> std::io::Seek for FixedSizeChunkedBytesCursor<'a, T> {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
// Mostly copied from io::Cursor::seek().
use std::io::SeekFrom;
let (base_pos, offset) = match pos {
SeekFrom::Start(n) => {
self.position = usize::try_from(n).unwrap().min(self.total_size);
return Ok(self.position as u64);
},
SeekFrom::End(n) => (self.total_size as u64, n),
SeekFrom::Current(n) => (self.position as u64, n),
};
match base_pos.checked_add_signed(offset) {
Some(n) => {
self.position = usize::try_from(n).unwrap();
Ok(self.position as u64)
},
None => Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"invalid seek to a negative or overflowing position",
)),
}
}
}
View on GitHub (pinned to fe841f959e)