astrid-runtime/astrid · error
invalid Astrid volume record magic at
Error message
invalid Astrid volume record magic at {offset} What it means
read_header reads the fixed-size record prefix and requires it to begin with RECORD_MAGIC. A mismatch means the bytes at the given offset are not the start of a valid volume record, so recovery/commit decoding cannot proceed and raises InvalidData with the offending offset included in the message.
Solutions
- Use the reported offset to inspect the file (`dd`/`xxd` around that offset) and confirm the corruption extent.
- Let recovery stop at the last valid commit — treat records after the bad offset as lost and rely on the last consistent snapshot.
- Verify writer/reader astrid-storage versions match.
- Restore the volume from backup if corruption precedes the last valid commit.
Defensive patterns
Strategy: try-catch
Try / catch
match recover_container(&mut file) {
Err(e) if e.kind() == io::ErrorKind::InvalidData
&& e.to_string().starts_with("invalid Astrid volume record magic") => {
eprintln!("record corruption: {e}; falling back to last valid commit");
/* open read-only at last valid snapshot or restore from backup */
}
other => other,
} Prevention
- Ensure clean shutdown (sync_all) so no torn records are left behind.
- Run recovery promptly after a crash instead of appending to a suspect stream.
- Monitor storage health (bit rot) and keep volume backups.
- Keep record format versions aligned between writer and reader.
When it happens
Trigger: recover_from_headers or read_commit walking to an offset whose bytes don't start with RECORD_MAGIC — a corrupted record, a torn/partial write, following a stale next-record pointer, or reading a volume written by an incompatible version.
Common situations: Power loss / crash mid-write leaving a half-written record; the recovery pointer referencing a record that was later overwritten; bit rot on the storage device; version skew between the writer's record layout and the reader.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- invalid Astrid volume header
- invalid Astrid volume record length at
- invalid interior Astrid volume record length at
- message
- unknown Astrid volume operation
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/671f36c57dfd34ce.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-storage/src/volume/hosted/recover.rs:360
.ok_or_else(|| invalid_transition("missing metadata transaction payload"))?;
let mutations = decode_metadata_mutations(payload)?;
apply_metadata_mutations(regions, &mutations)?;
},
}
Ok(())
}
fn read_header(file: &File, offset: u64, physical_len: u64) -> io::Result<Option<RecordHeader>> {
let remaining = physical_len.saturating_sub(offset);
if remaining < RECORD_FIXED_BYTES as u64 {
return Ok(None);
}
#[cfg(test)]
READ_HEADER_COUNT.with(|count| count.set(count.get().saturating_add(1)));
let mut fixed = [0_u8; RECORD_FIXED_BYTES];
read_exact_at(file, offset, &mut fixed)?;
if fixed[..RECORD_MAGIC.len()] != RECORD_MAGIC {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("invalid Astrid volume record magic at {offset}"),
));
}
let total_len = u64::from_le_bytes(read_array::<8>(&fixed[8..16])?);
let name_length = usize::from(u16::from_le_bytes(read_array::<2>(&fixed[25..27])?));
let payload_len = u64::from_le_bytes(read_array::<8>(&fixed[35..43])?);
let declared = (RECORD_FIXED_BYTES as u64)
.checked_add(name_length as u64)
.and_then(|value| value.checked_add(payload_len));
if total_len < RECORD_FIXED_BYTES as u64
|| declared != Some(total_len)
|| name_length == 0
|| name_length > MAX_REGION_NAME_BYTES
{
return handle_bad_length(file, offset, physical_len, total_len, remaining);
}
if total_len > remaining {View on GitHub (pinned to affd8760f4)