tikv/tikv · error

log file {name} range [{start}, {end}) exceeds cached physic

Error message

log file {name} range [{start}, {end}) exceeds cached physical file {} length {}

What it means

checked_get_range validates that the requested [start, end) byte range fits within the cached physical file's content before slicing. If end exceeds the cached content length, it throws this InvalidData io::Error, preventing out-of-bounds reads on the in-memory cache buffer.

Source

Thrown at components/compact-log-backup/src/cache.rs:371

        io::Error::new(
            io::ErrorKind::InvalidData,
            format!("log file {name} offset {offset} is too large"),
        )
    })?;
    let end = usize::try_from(offset.checked_add(length).ok_or_else(|| {
        io::Error::new(
            io::ErrorKind::InvalidData,
            format!("log file {name} offset {offset} + length {length} overflows"),
        )
    })?)
    .map_err(|_| {
        io::Error::new(
            io::ErrorKind::InvalidData,
            format!("log file {name} offset {offset} + length {length} is too large"),
        )
    })?;
    if end > content.len() {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "log file {name} range [{start}, {end}) exceeds cached physical file {} length {}",
                name,
                content.len()
            ),
        ));
    }
    Ok(content.slice(start..end))
}

#[cfg(test)]
mod tests {
    use super::*;

    fn ready_part(decision: CacheDecision) -> Bytes {
        match decision {
            CacheDecision::Ready(part) => part,

View on GitHub (pinned to 78aedc1c81)

Solutions

  1. Invalidate and refetch the cached file to ensure the cache holds the complete content.
  2. Re-download the log file from storage and verify its checksum/length against metadata.
  3. Clamp or validate requested ranges against the actual file length recorded when caching.
  4. Re-run log backup compaction if the source file itself is truncated.

Example fix

// before
let slice = checked_get_range(&content, name, off, len)?;
// after
let end = off.checked_add(len).ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "overflow"))?;
assert!(end <= content.len(), "range exceeds cached file {name}");
let slice = checked_get_range(&content, name, off, len)?;
Defensive patterns

Strategy: validation

Validate before calling

fn range_fits(offset: u64, length: u64, cached_len: usize) -> bool {
    offset.checked_add(length).map_or(false, |end| (end as usize) <= cached_len)
}

Try / catch

if let Err(e) = cache_decision(...).await {
    if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("exceeds cached physical file") {
        cache.invalidate(name); // refetch the full file
    }
    return Err(e);
}

Prevention

When it happens

Trigger: cache_decision requests a range whose end (offset + length) is larger than the actual size of the cached log file — e.g. the cached copy is shorter than the metadata claims (truncated download or stale cache entry).

Common situations: A log file was truncated on object storage but metadata still refers to the original length; a partially downloaded/prefetched cache entry; mismatch between cached file version and the referenced record offsets.

Related errors


AI-assisted analysis of tikv/tikv@78aedc1c81 (2026-09-03). Data as JSON: /api/errors/e05e4439a0204aa5. Report an issue: GitHub.