tursodatabase/turso · error
invalid MVCC logical log magic
Error message
invalid MVCC logical log magic
What it means
The first four bytes of the .db-log must equal MVCC_LOG_MAGIC 0x4C4D4C32; anything else means the file at the .db-log path is not an lml3 MVCC logical log. Unlike the version-mismatch error, a bad magic is not treated as a 'portable' fallback case (is_nonportable_mvcc_log_error only matches the version message), so it surfaces as a hard HTTP 500.
Source
Thrown at cli/sync_server.rs:985
running_crc = frame_crc;
offset = frame_end;
crc_by_offset.push((offset as u64, running_crc));
}
Ok(MvccLogSnapshot {
end_offset: offset as u64,
crc_by_offset,
})
}
fn is_nonportable_mvcc_log_error(err: &anyhow::Error) -> bool {
let message = err.to_string();
message.starts_with("unsupported MVCC logical log version ")
}
fn validate_mvcc_log_header(log: &[u8]) -> Result<()> {
if read_u32_le(log, 0)? != MVCC_LOG_MAGIC {
return Err(anyhow!("invalid MVCC logical log magic"));
}
if log[4] != MVCC_LOG_VERSION {
return Err(anyhow!("unsupported MVCC logical log version {}", log[4]));
}
if log[5] & 0b1111_1110 != 0 {
return Err(anyhow!("invalid MVCC logical log header flags"));
}
let header_len = u16::from_le_bytes([log[6], log[7]]) as usize;
if header_len != MVCC_LOG_HEADER_SIZE {
return Err(anyhow!(
"invalid MVCC logical log header length: {header_len}"
));
}
if log[MVCC_LOG_HEADER_RESERVED_START..MVCC_LOG_HEADER_CRC_START]
.iter()
.any(|byte| *byte != 0)
{
return Err(anyhow!(View on GitHub (pinned to bad083fafb)
Solutions
- Confirm the .db-log sitting next to the .db was written by the same engine and run (check the first bytes).
- Remove the wrong file: the server falls back to replace-base pages and clients re-bootstrap.
- Recreate the sync setup (.db plus .db-log) from a consistent source.
Defensive patterns
Strategy: validation
Validate before calling
fn is_lml3_log(path: &std::path::Path) -> bool {
let mut magic = [0u8; 4];
std::fs::File::open(path)
.and_then(|mut f| std::io::Read::read_exact(&mut f, &mut magic))
.map(|_| u32::from_le_bytes(magic) == 0x4C4D4C32)
.unwrap_or(false)
} Try / catch
On 500 'invalid MVCC logical log magic', do not retry: verify the file at the .db-log path belongs to this database; remove or replace it so the server serves replace-base pages.
Prevention
- Never place foreign files at the .db-log path.
- Verify magic and version bytes with tooling that manipulates sync files.
- Keep one .db-log per .db and never copy logs between databases.
When it happens
Trigger: A foreign or corrupt file at the .db-log path: another database's log, a text file, bit rot, or a format whose magic differs; the header check runs before any fallback logic can downgrade the error.
Common situations: Swapping or misplacing sync files between databases; a different tool writing a file with the same name; storage-level corruption.
Related errors
- truncated MVCC logical log header: len={} header_size={}
- invalid MVCC logical log header flags
- unsupported MVCC logical log version {}
- MVCC logical pull revision is from the future: client_offset
- MVCC logical pull offset is not a transaction boundary: {off
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/96f42920d8ab5471.
Report an issue: GitHub.