astrid-runtime/astrid · error

legacy revocation file exceeds migration cap

Error message

legacy revocation file exceeds migration cap

What it means

Size guard in read_legacy_bytes: the legacy revocation JSON exceeded MAX_REVOCATIONS_FILE_BYTES, so it is refused before being parsed — an unexpectedly huge file suggests corruption or tampering rather than a legitimate index.

Solutions

  1. Inspect the file; truncate or split it if it grew abnormally
  2. Complete the migration into the control KV and remove the legacy file
  3. Restore a sane legacy file from backup, then re-run startup
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at crates/astrid-gateway/src/revocations.rs:97 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at crates/astrid-gateway/src/revocations.rs:97

fn read_legacy_bytes(path: &std::path::Path) -> anyhow::Result<Vec<u8>> {
    #[cfg(unix)]
    let file = {
        use std::os::unix::fs::OpenOptionsExt as _;
        std::fs::OpenOptions::new()
            .read(true)
            .custom_flags(nix::libc::O_NOFOLLOW | nix::libc::O_CLOEXEC)
            .open(path)
            .with_context(|| format!("open legacy revocation file {}", path.display()))?
    };
    #[cfg(not(unix))]
    let file = std::fs::File::open(path)
        .with_context(|| format!("open legacy revocation file {}", path.display()))?;
    let mut bytes = Vec::new();
    file.take(MAX_REVOCATIONS_FILE_BYTES.saturating_add(1))
        .read_to_end(&mut bytes)
        .with_context(|| format!("read legacy revocation file {}", path.display()))?;
    if bytes.len() as u64 > MAX_REVOCATIONS_FILE_BYTES {
        anyhow::bail!("legacy revocation file exceeds migration cap");
    }
    Ok(bytes)
}

fn decode_epoch(bytes: &[u8], key: &str) -> anyhow::Result<u64> {
    let raw: [u8; 8] = bytes.try_into().map_err(|_| {
        anyhow::anyhow!(
            "revocation KV value for {key:?} has {} bytes; expected 8",
            bytes.len()
        )
    })?;
    Ok(u64::from_le_bytes(raw))
}

fn encode_epoch(epoch: u64) -> Vec<u8> {
    epoch.to_le_bytes().to_vec()
}

View on GitHub (pinned to affd8760f4)