{"record":{"id":"d8371e2a7e399d39","repo":"BoundaryML/baml","slug":"profiling-usage-ledger-checksum-mismatch","errorCode":null,"errorMessage":"profiling usage ledger checksum mismatch","messagePattern":"profiling usage ledger checksum mismatch","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_prof_store/src/prof/backend/store.rs","lineNumber":1664,"sourceCode":"\n    let mut total = USAGE_STATE_BYTES;\n    scan(root, root, &mut total)?;\n    Ok(total)\n}\n\nfn read_usage_state(root: &Path) -> io::Result<u64> {\n    let usage_state_len = usize::try_from(USAGE_STATE_BYTES).expect(\"fixed usage state fits usize\");\n    let mut bytes = Vec::with_capacity(usage_state_len);\n    File::open(root.join(\"usage.state\"))?.read_to_end(&mut bytes)?;\n    if bytes.len() != usage_state_len || &bytes[..8] != USAGE_MAGIC {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            \"invalid profiling usage ledger\",\n        ));\n    }\n    let expected: [u8; 32] = Sha256::digest(&bytes[..16]).into();\n    if bytes[16..] != expected {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            \"profiling usage ledger checksum mismatch\",\n        ));\n    }\n    Ok(u64::from_be_bytes(\n        bytes[8..16].try_into().expect(\"fixed-width usage\"),\n    ))\n}\n\nfn write_usage_state(root: &Path, usage: u64, platform: &dyn StorePlatform) -> io::Result<()> {\n    let usage_state_len = usize::try_from(USAGE_STATE_BYTES).expect(\"fixed usage state fits usize\");\n    let mut bytes = Vec::with_capacity(usage_state_len);\n    bytes.extend_from_slice(USAGE_MAGIC);\n    bytes.extend_from_slice(&usage.to_be_bytes());\n    let checksum: [u8; 32] = Sha256::digest(&bytes).into();\n    bytes.extend_from_slice(&checksum);\n    let temporary = root.join(\"tmp/usage-state.pending\");\n    let mut file = OpenOptions::new()","sourceCodeStart":1646,"sourceCodeEnd":1682,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_prof_store/src/prof/backend/store.rs#L1646-L1682","documentation":"The usage ledger stores its value plus a SHA-256 checksum over the first 16 bytes (magic + 8-byte big-endian counter). read_usage_state recomputes the digest and compares it to bytes[16..]; a mismatch raises InvalidData 'profiling usage ledger checksum mismatch', meaning the ledger content was altered or corrupted after it was written.","triggerScenarios":"Reading usage.state whose first 16 bytes (magic+counter) no longer match the stored 32-byte SHA-256 digest — e.g. hand-edited counter bytes, torn write, or bit rot in the first 16 bytes.","commonSituations":"Someone tried to tamper with the recorded usage counter; a crash/power loss during the ledger write left mismatched bytes; disk corruption; partial copy of the file.","solutions":["Delete usage.state so the store rebuilds the ledger from the actual on-disk segment sizes.","Restore usage.state from a known-good backup.","Check storage health (dmesg/SMART) if corruption recurs; run the store on reliable media.","Do not hand-edit the ledger — always update usage through the store's own APIs so the checksum stays consistent."],"exampleFix":"// shell\n// before: usage.state checksum mismatch (edited counter)\n// after\nrm <store-root>/usage.state  # ledger is recomputed from segments on next open","handlingStrategy":"validation","validationCode":"let bytes = fs::read(root.join(\"usage.state\"))?;\nlet expected: [u8; 32] = Sha256::digest(&bytes[..16]).into();\nif bytes.len() == 48 && bytes[16..] != expected {\n    // checksum mismatch: delete the ledger so it is rebuilt from segments\n}","typeGuard":null,"tryCatchPattern":"match read_usage_state(&root) {\n    Ok(usage) => usage,\n    Err(e) if e.to_string().contains(\"checksum mismatch\") => {\n        let _ = fs::remove_file(root.join(\"usage.state\"));\n        rebuild_usage_from_segments(&root)\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Always update usage through the store's own APIs so checksums stay consistent","Never edit the ledger bytes manually","Monitor storage health if corruption recurs (SMART/dmesg)","Restore the ledger only from backups taken while the process was stopped"],"tags":["rust","io","checksum","corruption","profiling"],"backgroundTag":"checksum-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}