clockworklabs/SpacetimeDB · error · io::Error

allocation size overflow

Error message

allocation size overflow

What it means

next_page_multiple rounds a byte size up to the next multiple of PAGE_SIZE. When the input is already page-aligned it is returned unchanged; otherwise it computes size + (PAGE_SIZE - remainder) with checked_add. Only a size within PAGE_SIZE of u64::MAX that is not page-aligned makes the addition overflow, producing ErrorKind::InvalidInput, 'allocation size overflow'. Callers pass either a write end position or pos + 1 from Segment::write.

Source

Thrown at crates/dst/src/sim/commitlog.rs:459

}

impl io::Seek for ReadOnlySegment {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.inner.seek(pos)
    }
}

impl SegmentLen for ReadOnlySegment {}

fn next_page_multiple(size: u64) -> io::Result<u64> {
    let page = PAGE_SIZE as u64;
    let remainder = size % page;
    if remainder == 0 {
        return Ok(size);
    }

    size.checked_add(page - remainder)
        .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "allocation size overflow"))
}

fn enospc() -> io::Error {
    io::Error::new(io::ErrorKind::StorageFull, "no space left on device")
}

#[cfg(test)]
mod tests {
    use std::io::{Read, Seek, Write};

    use super::*;

    fn segment() -> Segment {
        Segment::from_shared(Arc::new(Mutex::new(u64::MAX)), Arc::new(RwLock::new(Storage::new())))
    }

    #[test]
    fn write_overwrites_at_seek_position() {

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Keep test write positions far from u64::MAX so rounding never overflows
  2. If seen outside tests, audit how the Segment position became huge (seek corruption, fixture bug)
  3. Bound accepted write sizes/positions at your API boundary before they reach the commitlog

Example fix

// before
let end = u64::MAX - 3; // non-page-aligned, near max
next_page_multiple(end)?; // InvalidInput: allocation size overflow

// after
const MAX_SEG_END: u64 = u64::MAX - (u64::MAX % 4096) - 4096; // keep headroom
assert!(end <= MAX_SEG_END, "write end too large");
Defensive patterns

Strategy: validation

Validate before calling

const PAGE: u64 = 4096;
fn page_multiple_fits(size: u64) -> bool {
    let rem = size % PAGE;
    rem == 0 || size <= u64::MAX - (PAGE - rem)
}

Try / catch

// surfaced via Segment::write; see write's own InvalidInput handling:
match seg.write(buf) {
    Err(ref e) if e.kind() == std::io::ErrorKind::InvalidInput
        && e.to_string().contains("overflow") => { /* position/size corrupted: investigate */ }
    r => r?,
}

Prevention

When it happens

Trigger: A requested write whose end position (pos + buf.len()) is non-page-aligned and within PAGE_SIZE of u64::MAX; a position of exactly u64::MAX - k for small k feeding the minimum-allocation path; again only realistic in adversarial tests since the shared space budget triggers StorageFull long before.

Common situations: Edge-case unit tests probing allocation at the top of the u64 range; production occurrence indicates a corrupted position value, not a real allocation request.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/33de33e156a04622. Report an issue: GitHub.