spacejam/sled · error
crc mismatch for read of batch frame
Error message
crc mismatch for read of batch frame
What it means
After the frame length, read_frame reads the payload plus a trailing CRC and verifies it. If the recorded CRC differs from the CRC computed over the payload, the batch frame's contents are corrupt and it is rejected (after logging a warning) instead of being applied.
Solutions
- Restore metadata/log files from backup, or let the system rebuild them from other durable state if possible
- Remove/rename the corrupt log segment so recovery can resynchronize from earlier valid frames (accepting data loss for that segment)
- Check storage health (SMART/fsck) and fix underlying hardware issues
- Recreate or re-import the database if corruption is widespread
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure sufficient free space and that the log directory is writable before opening
let stat = nix::sys::statvfs::stat(&path)?;
if stat.blocks_available < min_free_blocks { return Err(anyhow!("insufficient space for metadata writes")); } Try / catch
match Db::open(&path) {
Ok(db) => db,
Err(e) if e.to_string().contains("crc mismatch for read of batch frame") => {
// payload corrupted: restore metadata backup or rebuild segment
repair_or_restore_metadata(&path)?;
Db::open(&path)?
}
Err(e) => return Err(e.into()),
} Prevention
- Use reliable, fsync-respecting storage to avoid torn batch writes
- Keep metadata backups and test restores
- Avoid power-cut scenarios (UPS, clean shutdown handlers)
- Verify file integrity after copying databases
When it happens
Trigger: Reading a metadata log/snapshot batch whose payload bytes were modified after write: torn write during a crash, bit rot, or partial disk flush.
Common situations: Power loss mid-write during metadata persistence; failing drives; interrupted file copies of the database directory.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- corrupt frame length
- encountered corrupted settings cookie with mismatched CRC.
- crc mismatch - data corruption detected
- corrupt object ID 0 somehow passed crc check
- Db's LEAF_FANOUT const generic must be 3 or greater.
AI-assisted analysis of spacejam/sled@e449d17111 (2026-09-12).
Data as JSON: /api/errors/402eeb60057d6a2d.
Report an issue: GitHub.
Appendix: source
Thrown at src/metadata_store.rs:545
reusable_frame_buffer.reserve(len + 12);
unsafe {
reusable_frame_buffer.set_len(len + 12);
}
reusable_frame_buffer[..8].copy_from_slice(&frame_size_with_crc_buf);
fallible!(file.read_exact(&mut reusable_frame_buffer[8..]));
let crc_actual = crc32fast::hash(&reusable_frame_buffer[..len + 8]) ^ 0xAF;
let crc_recorded = u32::from_le_bytes([
reusable_frame_buffer[len + 8],
reusable_frame_buffer[len + 9],
reusable_frame_buffer[len + 10],
reusable_frame_buffer[len + 11],
]);
if crc_actual != crc_recorded {
log::warn!("encountered incorrect crc for batch in log");
return Err(annotate!(io::Error::new(
io::ErrorKind::InvalidData,
"crc mismatch for read of batch frame",
)));
}
let mut ret = vec![];
let mut decoder = ZstdDecoder::new(&reusable_frame_buffer[8..len + 8])
.expect("failed to create zstd decoder");
let mut object_id_buf: [u8; 8] = [0; 8];
let mut collection_id_buf: [u8; 8] = [0; 8];
let mut location_buf: [u8; 8] = [0; 8];
let mut low_key_len_buf: [u8; 8] = [0; 8];
let mut low_key_buf = vec![];
loop {
let first_read_res = decoder
.read_exact(&mut object_id_buf)View on GitHub (pinned to e449d17111)