tursodatabase/turso · error · anyhow::Error

MVCC logical log extension record count without extension…

Error message

MVCC logical log extension record count without extension block at offset {offset}

What it means

An internal consistency rule of extended frames: if the extension-block size (u64 at offset+24) is zero, the extension record count (u32 at offset+32) must also be zero. A nonzero count with no block is a contradictory frame that the reader refuses rather than mis-parse.

Solutions

  1. Restore the log from backup or regenerate it; the frame is internally inconsistent
  2. If you wrote the frame producer, assert block-size and record-count agreement in tests
Defensive patterns

Strategy: try-catch

Try / catch

// Extension-block invariants are internal consistency rules;
// any violation means corruption - restore or regenerate.
let snapshot = scan_mvcc_log(&log)
    .map_err(|err| anyhow!("MVCC log frame metadata inconsistent: {err}"))?;

Prevention

When it happens

Trigger: read_mvcc_frame_boundary sees extension_size == 0 while extension_record_count != 0 on a frame during scan_mvcc_log.

Common situations: Corrupted extension header fields; a writer bug that emits counts without blocks; hand-edited or partially overwritten frames.

Related errors


AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-08-20). Data as JSON: /api/errors/af998367bdb2f3f4. Report an issue: GitHub.

Appendix: source

Thrown at cli/sync_server.rs:1178

        MVCC_TX_HEADER_SIZE
    };
    if log.len() - offset < header_size + MVCC_TX_TRAILER_SIZE {
        return Ok(None);
    }
    let payload_size = usize::try_from(read_u64_le(log, offset + 4)?)
        .map_err(|_| anyhow!("MVCC logical log payload size overflows usize"))?;
    let extension_size = if has_extension_header {
        let extension_size = usize::try_from(read_u64_le(log, offset + 24)?)
            .map_err(|_| anyhow!("MVCC logical log extension size overflows usize"))?;
        let extension_record_count = read_u32_le(log, offset + 32)?;
        let frame_flags = read_u32_le(log, offset + 36)?;
        if frame_flags & !MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK != 0 {
            return Err(anyhow!(
                "unsupported MVCC logical log frame flags at offset {offset}: {frame_flags:#x}"
            ));
        }
        if extension_size == 0 && extension_record_count != 0 {
            return Err(anyhow!(
                "MVCC logical log extension record count without extension block at offset {offset}"
            ));
        }
        if extension_size > 0 && frame_flags & MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK == 0 {
            return Err(anyhow!(
                "MVCC logical log extension block missing flag at offset {offset}"
            ));
        }
        extension_size
    } else {
        0
    };
    let trailer_start = offset
        .checked_add(header_size)
        .and_then(|value| value.checked_add(payload_size))
        .and_then(|value| value.checked_add(extension_size))
        .ok_or_else(|| anyhow!("MVCC logical log frame offset overflow"))?;
    let frame_end = trailer_start

View on GitHub (pinned to 492c4a71cd)