spacejam/sled · error

corrupt object ID 0 somehow passed crc check

Error message

corrupt object ID 0 somehow passed crc check

What it means

Frames reference objects by a nonzero ObjectId; ObjectId::new returns None for 0, which is reserved/invalid. Reaching this error means the object ID bytes decoded to 0 even though the frame's length CRC passed — a state the format should make impossible — so it is treated as corruption and surfaced explicitly.

Solutions

  1. Restore the metadata files from backup, as the frame is unrecoverable in place
  2. Drop/rebuild the affected metadata segment and let recovery replay from a valid point
  3. Investigate the storage device for zero-fill anomalies (firmware updates, sector scans)
  4. Recreate the database if corruption recurs
Defensive patterns

Strategy: try-catch

Validate before calling

// detect zero-filled / truncated regions in db files before opening
let sample = std::fs::read(&path.join("blob"))?.into_iter().take(4096).collect::<Vec<_>>();
if sample.iter().all(|&b| b == 0) { return Err(anyhow!("db file looks zero-filled/corrupt")); }

Try / catch

match Db::open(&path) {
    Ok(db) => db,
    Err(e) if e.to_string().contains("corrupt object ID") => {
        restore_from_backup(&path)?; // invariant violated on disk
        Db::open(&path)?
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Reading a metadata log/snapshot frame whose object ID bytes were zeroed by corruption (e.g. zero-filled sectors after a torn write) that nonetheless had a passing length CRC.

Common situations: Storage regions zeroed by drive firmware bugs or partial TRIM behavior; crash-during-write leaving zeros; manual file tampering.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of spacejam/sled@e449d17111 (2026-09-12). Data as JSON: /api/errors/5a6c5aa3bb52d1a2. Report an issue: GitHub.

Appendix: source

Thrown at src/metadata_store.rs:581

            .read_exact(&mut object_id_buf)
            .and_then(|_| decoder.read_exact(&mut collection_id_buf))
            .and_then(|_| decoder.read_exact(&mut location_buf))
            .and_then(|_| decoder.read_exact(&mut low_key_len_buf));

        if let Err(e) = first_read_res {
            if e.kind() != io::ErrorKind::UnexpectedEof {
                return Err(e);
            } else {
                break;
            }
        }

        let object_id_u64 = u64::from_le_bytes(object_id_buf);

        let object_id = if let Some(object_id) = ObjectId::new(object_id_u64) {
            object_id
        } else {
            return Err(annotate!(io::Error::new(
                io::ErrorKind::InvalidData,
                "corrupt object ID 0 somehow passed crc check"
            )));
        };

        let collection_id = CollectionId(u64::from_le_bytes(collection_id_buf));
        let location = u64::from_le_bytes(location_buf);

        let low_key_len_raw = u64::from_le_bytes(low_key_len_buf);
        let low_key_len = usize::try_from(low_key_len_raw).unwrap();

        low_key_buf.reserve(low_key_len);
        unsafe {
            low_key_buf.set_len(low_key_len);
        }

        decoder
            .read_exact(&mut low_key_buf)

View on GitHub (pinned to e449d17111)