{"record":{"id":"5a6c5aa3bb52d1a2","repo":"spacejam/sled","slug":"corrupt-object-id-0-somehow-passed-crc-check","errorCode":null,"errorMessage":"corrupt object ID 0 somehow passed crc check","messagePattern":"corrupt object ID 0 somehow passed crc check","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/metadata_store.rs","lineNumber":581,"sourceCode":"            .read_exact(&mut object_id_buf)\n            .and_then(|_| decoder.read_exact(&mut collection_id_buf))\n            .and_then(|_| decoder.read_exact(&mut location_buf))\n            .and_then(|_| decoder.read_exact(&mut low_key_len_buf));\n\n        if let Err(e) = first_read_res {\n            if e.kind() != io::ErrorKind::UnexpectedEof {\n                return Err(e);\n            } else {\n                break;\n            }\n        }\n\n        let object_id_u64 = u64::from_le_bytes(object_id_buf);\n\n        let object_id = if let Some(object_id) = ObjectId::new(object_id_u64) {\n            object_id\n        } else {\n            return Err(annotate!(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"corrupt object ID 0 somehow passed crc check\"\n            )));\n        };\n\n        let collection_id = CollectionId(u64::from_le_bytes(collection_id_buf));\n        let location = u64::from_le_bytes(location_buf);\n\n        let low_key_len_raw = u64::from_le_bytes(low_key_len_buf);\n        let low_key_len = usize::try_from(low_key_len_raw).unwrap();\n\n        low_key_buf.reserve(low_key_len);\n        unsafe {\n            low_key_buf.set_len(low_key_len);\n        }\n\n        decoder\n            .read_exact(&mut low_key_buf)","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/spacejam/sled/blob/e449d17111f4a097e1c66b6db241962ccb6a4136/src/metadata_store.rs#L563-L599","documentation":"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.","triggerScenarios":"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.","commonSituations":"Storage regions zeroed by drive firmware bugs or partial TRIM behavior; crash-during-write leaving zeros; manual file tampering.","solutions":["Restore the metadata files from backup, as the frame is unrecoverable in place","Drop/rebuild the affected metadata segment and let recovery replay from a valid point","Investigate the storage device for zero-fill anomalies (firmware updates, sector scans)","Recreate the database if corruption recurs"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// detect zero-filled / truncated regions in db files before opening\nlet sample = std::fs::read(&path.join(\"blob\"))?.into_iter().take(4096).collect::<Vec<_>>();\nif sample.iter().all(|&b| b == 0) { return Err(anyhow!(\"db file looks zero-filled/corrupt\")); }","typeGuard":null,"tryCatchPattern":"match Db::open(&path) {\n    Ok(db) => db,\n    Err(e) if e.to_string().contains(\"corrupt object ID\") => {\n        restore_from_backup(&path)?; // invariant violated on disk\n        Db::open(&path)?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep verified backups; zeroed regions indicate serious storage faults","Update drive firmware and run sector scans if zero-filling recurs","Never hand-edit database files","Use UPS/clean shutdown to avoid writes interrupted by power loss"],"tags":["rust","corruption","metadata","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e449d17111f4a097e1c66b6db241962ccb6a4136","analyzedAt":"2026-09-12T01:23:10.985Z","contentChangedAt":"2026-09-12T01:23:10.985Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}