astrid-runtime/astrid · error
invalid Astrid volume record length at
Error message
invalid Astrid volume record length at {offset} What it means
A record header claims a total_len greater than the bytes remaining in the region, and no physically valid record follows it, so recovery cannot interpret the tail as another record. Because this is the final bad-length record (no valid successor found), recovery reports plain 'invalid record length' InvalidData for that offset.
Solutions
- Check whether the volume file is complete (size matches what the writer expected); restore or re-sync an incompletely copied/truncated file.
- Recover from backup or the last committed footer/commit point.
- If only the tail record is affected and the region tolerates losing the last write, discard the torn tail and re-open the volume.
- Investigate why the writer was interrupted (OOM, disk-full, kill -9) before reusing the volume.
Defensive patterns
Strategy: try-catch
Validate before calling
// cheap pre-check: ensure expected file size is present
let meta = file.metadata()?;
if meta.len() < expected_min_volume_size { return Err("volume file truncated"); } Try / catch
match recover_from_headers(&file) {
Err(e) if e.kind() == io::ErrorKind::InvalidData && e.to_string().contains("invalid Astrid volume record length") => {
// treat as torn tail: recover to last good record or restore backup
}
other => other?,
} Prevention
- Use atomic/append-safe shutdown paths; avoid kill -9 during writes.
- Ensure adequate disk space so appends never complete partially.
- Verify file integrity (size/checksum) after copying volumes between hosts.
- Restore from backup rather than replaying a truncated tail when in doubt.
When it happens
Trigger: handle_bad_length (from read_header) finds total_len > remaining and has_physically_valid_record_after(offset+1) is false — the tail of the volume contains a header whose length cannot fit, with no resynchronizable record after it (e.g. torn final write).
Common situations: The process crashed mid-append leaving a partial record header at the tail; the volume file was truncated (copied incompletely, disk full during write); a caller recovers a file captured mid-write.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- invalid interior Astrid volume record length at
- truncated Astrid volume record
- audit read failed
- destination.as_str()
- invalid Astrid volume record magic at
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b3606c3dfed94f91.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-storage/src/volume/hosted/recover.rs:423
fn handle_bad_length(
file: &File,
offset: u64,
physical_len: u64,
total_len: u64,
remaining: u64,
) -> io::Result<Option<RecordHeader>> {
if total_len > remaining
&& has_physically_valid_record_after(file, offset.saturating_add(1), physical_len)?
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("invalid interior Astrid volume record length at {offset}"),
));
}
if total_len > remaining {
return Ok(None);
}
Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("invalid Astrid volume record length at {offset}"),
))
}
fn read_record_payload(file: &File, header: &RecordHeader) -> io::Result<Option<Vec<u8>>> {
if header.operation == Operation::Write {
return Ok(None);
}
let max_payload = if header.operation == Operation::Commit {
MAX_COMMIT_SNAPSHOT_BYTES
} else {
MAX_METADATA_PAYLOAD_BYTES
};
if header.payload_len > max_payload {
return Err(invalid_transition(
"Astrid volume metadata payload exceeds the recovery bound",
));View on GitHub (pinned to affd8760f4)