{"record":{"id":"fbc1bb1637e1c611","repo":"tursodatabase/turso","slug":"invalid-mvcc-logical-log-header-length-header-le","errorCode":null,"errorMessage":"invalid MVCC logical log header length: {header_len}","messagePattern":"invalid MVCC logical log header length: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"cli/sync_server.rs","lineNumber":1111,"sourceCode":"fn is_nonportable_mvcc_log_error(err: &anyhow::Error) -> bool {\n    let message = err.to_string();\n    message.starts_with(\"unsupported MVCC logical log version \")\n}\n\nfn validate_mvcc_log_header(log: &[u8]) -> Result<()> {\n    if read_u32_le(log, 0)? != MVCC_LOG_MAGIC {\n        return Err(anyhow!(\"invalid MVCC logical log magic\"));\n    }\n    if log[4] != MVCC_LOG_VERSION {\n        return Err(anyhow!(\"unsupported MVCC logical log version {}\", log[4]));\n    }\n    if log[5] & 0b1111_1110 != 0 {\n        return Err(anyhow!(\"invalid MVCC logical log header flags\"));\n    }\n    let header_len = u16::from_le_bytes([log[6], log[7]]) as usize;\n    if header_len != MVCC_LOG_HEADER_SIZE {\n        return Err(anyhow!(\n            \"invalid MVCC logical log header length: {header_len}\"\n        ));\n    }\n    if log[MVCC_LOG_HEADER_RESERVED_START..MVCC_LOG_HEADER_CRC_START]\n        .iter()\n        .any(|byte| *byte != 0)\n    {\n        return Err(anyhow!(\n            \"MVCC logical log header reserved bytes must be zero\"\n        ));\n    }\n    let stored_crc = read_u32_le(log, MVCC_LOG_HEADER_CRC_START)?;\n    let mut crc_buf = [0u8; MVCC_LOG_HEADER_SIZE];\n    crc_buf.copy_from_slice(&log[..MVCC_LOG_HEADER_SIZE]);\n    crc_buf[MVCC_LOG_HEADER_CRC_START..MVCC_LOG_HEADER_SIZE].fill(0);\n    let expected_crc = crc32c::crc32c(&crc_buf);\n    if stored_crc != expected_crc {\n        return Err(anyhow!(\"MVCC logical log header checksum mismatch\"));\n    }","sourceCodeStart":1093,"sourceCodeEnd":1129,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/cli/sync_server.rs#L1093-L1129","documentation":"Bytes 6..8 of the MVCC logical log header hold a little-endian u16 header length that must equal MVCC_LOG_HEADER_SIZE (56). The check exists so the parser can locate the salt and CRC fields reliably; any other value means the header layout is not the one this build knows how to read.","triggerScenarios":"validate_mvcc_log_header computes u16::from_le_bytes([log[6], log[7]]) and finds a value != 56 while serving a logical /pull-updates request.","commonSituations":"A future format that grew the header; a header written in big-endian by mistake in a fork; garbage bytes from corruption or a partially written header after a crash during log creation.","solutions":["Restore the log from backup or regenerate it - a mismatched header length is not recoverable in place","Match the tursodb version that produced the file if the log came from another build","If forking the format, keep header_len in sync with MVCC_LOG_HEADER_SIZE and bump MVCC_LOG_VERSION together"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn mvcc_header_length_ok(log: &[u8]) -> bool {\n    log.len() >= 8\n        && u16::from_le_bytes([log[6], log[7]]) as usize == MVCC_LOG_HEADER_SIZE // 56\n}","typeGuard":null,"tryCatchPattern":"let snapshot = match scan_mvcc_log(&log) {\n    Ok(s) => s,\n    Err(err) if err.to_string().starts_with(\"invalid MVCC logical log header length\") => {\n        // layout mismatch: regenerate log, do not attempt partial reads\n        return rebuild_log_and_fallback();\n    }\n    Err(err) => return Err(err),\n};","preventionTips":["Treat header length as part of the format contract: change it only with a version bump","Verify the header length field in writer unit tests","Do not parse logs produced by unknown builds"],"tags":["mvcc","sync-server","header-validation","header-length","corruption"],"backgroundTag":"invalid-file-header","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"}