astrid-runtime/astrid · error

invalid Astrid volume header

Error message

invalid Astrid volume header

What it means

When opening an existing (non-empty) volume, the first VOLUME_MAGIC bytes are read and compared against the expected magic constant. A mismatch means the file was not created by this library or its header was overwritten/corrupted, so open aborts with InvalidData rather than parsing arbitrary data.

Solutions

  1. Inspect the file's first bytes (`xxd <file> | head`) to confirm whether it is an Astrid volume.
  2. Correct the configured path if you meant a different file.
  3. If the file is not a volume, create a new one via the library's create path (empty length triggers VOLUME_MAGIC write).
  4. Restore the volume from backup if the header was corrupted.

Example fix

// before
let volume = HostedVolume::open("/data/not-a-volume.bin")?;
// after
let volume = HostedVolume::open("/data/volumes/volume.astrid")?; // file starts with VOLUME_MAGIC
Defensive patterns

Strategy: validation

Validate before calling

fn looks_like_astrid_volume(path: &Path) -> std::io::Result<bool> {
    use std::io::Read;
    let mut f = std::fs::File::open(path)?;
    let mut magic = [0u8; 8]; // match VOLUME_MAGIC.len()
    let n = f.read(&mut magic)?;
    Ok(n == magic.len()) // compare against VOLUME_MAGIC in real usage
}

Try / catch

match HostedVolume::open(&path) {
    Err(e) if e.kind() == io::ErrorKind::InvalidData
        && e.to_string().contains("invalid Astrid volume header") => {
        eprintln!("{path:?} is not an Astrid volume; check path or recreate");
    }
    other => { /* ... */ }
}

Prevention

When it happens

Trigger: Opening a file that exists but was not created as an Astrid volume (magic bytes absent); a header overwritten by other data; a truncated/garbage file that is non-empty; pointing the config at the wrong file.

Common situations: Typos in the configured volume path resolving to some other file; another tool writing to the same file; partial download/copy of a volume; attempting to open a plain text/binary file as a volume.

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/d4081d2fbab8bbba. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-storage/src/volume/hosted/open.rs:111

                "Astrid volume is not a regular file",
            ));
        }
        file.try_lock_exclusive().map_err(|error| {
            if error.kind() == io::ErrorKind::WouldBlock {
                io::Error::new(io::ErrorKind::WouldBlock, "Astrid volume is already open")
            } else {
                error
            }
        })?;
        let length = file.metadata()?.len();
        if length == 0 {
            file.write_all(&VOLUME_MAGIC)?;
            file.sync_all()?;
        } else {
            let mut magic = [0_u8; VOLUME_MAGIC.len()];
            file.read_exact(&mut magic)?;
            if magic != VOLUME_MAGIC {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    "invalid Astrid volume header",
                ));
            }
        }
        let recovery = recover::recover_container(&mut file)?;
        if file.metadata()?.len() != recovery.valid_len && !recovery.footer_present {
            file.set_len(recovery.valid_len)?;
            file.sync_all()?;
        }
        let footer_pending = !recovery.footer_present;
        let mut state = ContainerState {
            file,
            sequence: recovery.sequence,
            valid_len: recovery.valid_len,
            durable_len: recovery.durable_len,
            last_commit_offset: recovery.last_commit_offset,
            last_commit_has_snapshot: recovery.last_commit_has_snapshot,

View on GitHub (pinned to affd8760f4)