{"record":{"id":"2c6ff5fa4469182c","repo":"tursodatabase/turso","slug":"unsupported-mvcc-logical-log-frame-flags-at-offset","errorCode":null,"errorMessage":"unsupported MVCC logical log frame flags at offset {offset}: {frame_flags:#x}","messagePattern":"unsupported MVCC logical log frame flags at offset (.+?): (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/sync_server.rs","lineNumber":1058,"sourceCode":"        ));\n    }\n    let header_size = if has_extension_header {\n        MVCC_TX_EXT_HEADER_SIZE\n    } else {\n        MVCC_TX_HEADER_SIZE\n    };\n    if log.len() - offset < header_size + MVCC_TX_TRAILER_SIZE {\n        return Ok(None);\n    }\n    let payload_size = usize::try_from(read_u64_le(log, offset + 4)?)\n        .map_err(|_| anyhow!(\"MVCC logical log payload size overflows usize\"))?;\n    let extension_size = if has_extension_header {\n        let extension_size = usize::try_from(read_u64_le(log, offset + 24)?)\n            .map_err(|_| anyhow!(\"MVCC logical log extension size overflows usize\"))?;\n        let extension_record_count = read_u32_le(log, offset + 32)?;\n        let frame_flags = read_u32_le(log, offset + 36)?;\n        if frame_flags & !MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK != 0 {\n            return Err(anyhow!(\n                \"unsupported MVCC logical log frame flags at offset {offset}: {frame_flags:#x}\"\n            ));\n        }\n        if extension_size == 0 && extension_record_count != 0 {\n            return Err(anyhow!(\n                \"MVCC logical log extension record count without extension block at offset {offset}\"\n            ));\n        }\n        if extension_size > 0 && frame_flags & MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK == 0 {\n            return Err(anyhow!(\n                \"MVCC logical log extension block missing flag at offset {offset}\"\n            ));\n        }\n        extension_size\n    } else {\n        0\n    };\n    let trailer_start = offset","sourceCodeStart":1040,"sourceCodeEnd":1076,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/cli/sync_server.rs#L1040-L1076","documentation":"Extension frames carry a u32 flags word at offset +36; this build defines only MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK. Any other bit set means the frame uses a format this binary does not know how to skip, so the scan rejects it instead of guessing the layout. It is the forward-compatibility guard: newer engines that define new flag bits will trip it on older readers, mirroring the version check in the header.","triggerScenarios":"Scanning an extension frame whose u32 flags at offset +36 contain bits outside MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK — typically a log written by a newer engine revision that defined new flags, read by an older sync server; also corrupted flags bytes.","commonSituations":"Rolling upgrades where the writer node upgrades first and emits new flag bits while the sync server still runs the old release; logs produced by feature-branch builds scanned by a main-branch server; fuzzed flag words.","solutions":["Upgrade the sync server (reader) to the engine version that wrote the log — new flag bits are a newer frame format.","Or regenerate the log with the current engine so it uses only known flags.","Keep both ends of sync on the same Turso release; treat this error like the nonportable-version error (is_nonportable_mvcc_log_error) rather than corruption."],"exampleFix":"// before\nlet snapshot = scan_mvcc_log(&log)?; // errors: unsupported ... frame flags at offset N\n\n// after: classify as a version-compat failure, not corruption\nlet snapshot = match scan_mvcc_log(&log) {\n    Ok(snapshot) => snapshot,\n    Err(err) if err.to_string().starts_with(\"unsupported MVCC logical log frame flags\") => {\n        return Err(err.context(\"sync server older than log writer; upgrade both ends\"));\n    }\n    Err(err) => return Err(err),\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn frame_flags_supported(log: &[u8], offset: usize) -> bool {\n    log.get(offset + 36..offset + 40).is_some_and(|b| {\n        let flags = u32::from_le_bytes(b.try_into().unwrap());\n        flags & !MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK == 0\n    })\n}","tryCatchPattern":"match scan_mvcc_log(&log) {\n    Ok(snapshot) => { /* serve deltas */ }\n    Err(err) if err.to_string().starts_with(\"unsupported MVCC logical log frame flags\") => {\n        // version-compat failure like is_nonportable_mvcc_log_error:\n        // upgrade the reader; do not partially trust the log\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Upgrade writer and reader engines together during rollouts.","Treat unknown-flag errors as nonportable-format errors, not corruption.","Add CI coverage that scans logs produced by the current engine with the shipped sync server."],"tags":["mvcc","turso","sync","version-compat","feature-flags"],"backgroundTag":"unsupported-format-flags","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}