{"record":{"id":"28cf88971cd0caf9","repo":"tursodatabase/turso","slug":"invalid-mvcc-logical-log-frame-end-magic-at-offset","errorCode":null,"errorMessage":"invalid MVCC logical log frame end magic at offset {offset}","messagePattern":"invalid MVCC logical log frame end magic at offset (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":500,"severity":"error","filePath":"cli/sync_server.rs","lineNumber":1211,"sourceCode":"        .and_then(|value| value.checked_add(payload_size))\n        .and_then(|value| value.checked_add(extension_size))\n        .ok_or_else(|| anyhow!(\"MVCC logical log frame offset overflow\"))?;\n    let frame_end = trailer_start\n        .checked_add(MVCC_TX_TRAILER_SIZE)\n        .ok_or_else(|| anyhow!(\"MVCC logical log frame end overflow\"))?;\n    if frame_end > log.len() {\n        return Ok(None);\n    }\n    let expected_crc = crc32c::crc32c_append(running_crc, &log[offset..trailer_start]);\n    let stored_crc = read_u32_le(log, trailer_start)?;\n    if stored_crc != expected_crc {\n        return Err(anyhow!(\n            \"MVCC logical log frame checksum mismatch at offset {offset}\"\n        ));\n    }\n    let end_magic = read_u32_le(log, trailer_start + 4)?;\n    if end_magic != MVCC_TX_END_MAGIC {\n        return Err(anyhow!(\n            \"invalid MVCC logical log frame end magic at offset {offset}\"\n        ));\n    }\n    Ok(Some((frame_end, stored_crc)))\n}\n\nfn read_u32_le(buf: &[u8], offset: usize) -> Result<u32> {\n    let bytes = buf\n        .get(offset..offset + 4)\n        .ok_or_else(|| anyhow!(\"buffer too short for u32 at offset {offset}\"))?;\n    Ok(u32::from_le_bytes(bytes.try_into().unwrap()))\n}\n\nfn read_u64_le(buf: &[u8], offset: usize) -> Result<u64> {\n    let bytes = buf\n        .get(offset..offset + 8)\n        .ok_or_else(|| anyhow!(\"buffer too short for u64 at offset {offset}\"))?;\n    Ok(u64::from_le_bytes(bytes.try_into().unwrap()))","sourceCodeStart":1193,"sourceCodeEnd":1229,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/cli/sync_server.rs#L1193-L1229","documentation":"Each frame trailer ends with MVCC_TX_END_MAGIC at trailer_start+4. The frame CRC only covers bytes before the trailer, so a corrupted end-magic word can pass the CRC check and fail here. It also fires when a wrong payload size shifts trailer_start into the middle of the payload (usually caught earlier by the CRC, making this a rare, narrow corruption signature).","triggerScenarios":"read_mvcc_frame_boundary reads the u32 at trailer_start+4 and finds anything other than MVCC_TX_END_MAGIC after the frame CRC already matched.","commonSituations":"A bit flip localized to the trailer's magic word; truncated-then-refilled files; layout desync from an earlier size-field corruption.","solutions":["Restore the log from backup or regenerate it","If it recurs, capture the offending frame bytes and check for storage-level corruption"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let snapshot = match scan_mvcc_log(&log) {\n    Ok(s) => s,\n    Err(err) if err.to_string().contains(\"frame end magic\") => {\n        // trailer magic corrupt (CRC passed, so damage is localized)\n        restore_or_rebuild()?\n    }\n    Err(err) => return Err(err),\n};","preventionTips":["Preserve the end-magic check when modifying the frame format","Treat repeated trailer-only corruption as a storage-hardware symptom","Keep backups so any single-frame corruption is a restore, not an investigation"],"tags":["mvcc","sync-server","magic","trailer","corruption"],"backgroundTag":"invalid-magic-number","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}