astrid-runtime/astrid · critical · anyhow::Error
immutable release manifest does not match the channel BLAKE3
Error message
immutable release manifest does not match the channel BLAKE3 digest
What it means
The BLAKE3 hash of the downloaded release manifest bytes does not equal the metadata_blake3 digest recorded in the signed channel pointer. This is an integrity check: the manifest has been corrupted, replaced, or the pointer is stale.
Source
Thrown at crates/astrid-cli/src/commands/update_channel.rs:570
|| kind != "nightly"
|| date.len() != 8
|| !date.bytes().all(|byte| byte.is_ascii_digit())
|| NaiveDate::parse_from_str(date, "%Y%m%d").is_err()
|| commit.len() != 40
|| !commit
.bytes()
.all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
{
return None;
}
Some(commit)
}
pub(super) fn verify_release_manifest(
bytes: &[u8],
pointer: &ChannelPointer,
) -> anyhow::Result<()> {
ensure!(
blake3::hash(bytes).to_hex().as_str() == pointer.release.metadata_blake3,
"immutable release manifest does not match the channel BLAKE3 digest"
);
let text = std::str::from_utf8(bytes).context("release manifest is not UTF-8")?;
let manifest: ReleaseManifest =
toml::from_str(text).context("release manifest is invalid TOML")?;
ensure!(
manifest.schema_version == 1
&& manifest.kind == "astrid-release"
&& manifest.product == PRODUCT
&& manifest.repository == REPOSITORY,
"release manifest identity is invalid"
);
ensure!(
manifest.version == pointer.release.version
&& manifest.tag == pointer.release.tag
&& manifest.source_commit == pointer.release.source_commit
&& manifest.release_workflow_identity == pointer.release.release_workflow_identity,View on GitHub (pinned to affd8760f4)
Solutions
- Re-fetch the channel pointer and manifest to rule out transient corruption
- Re-publish the channel so metadata_blake3 matches the current manifest
- Check for caching proxies/CDN serving outdated manifests
- Clear the local channel state and retry resolution
Defensive patterns
Strategy: retry
Validate before calling
let expected = &pointer.release.metadata_blake3;
if blake3::hash(bytes).to_hex().as_str() != expected {
eprintln!("manifest digest mismatch; re-fetch");
} Try / catch
loop {
match fetch_and_verify_manifest(&pointer) {
Ok(m) => break m,
Err(e) if attempts < 3 => attempts += 1,
Err(e) => return Err(e),
}
} Prevention
- Always verify hashes before trusting downloaded metadata
- Bypass CDNs/proxies when debugging digest mismatches
- Re-sign the pointer whenever the manifest changes
When it happens
Trigger: verify_release_manifest (called from resolve_signed_channel) hashes the fetched manifest bytes and compares against pointer.release.metadata_blake3; mismatch occurs on truncated downloads, a re-published manifest without updating the pointer, or a tampered manifest.
Common situations: Proxy/CDN serving a stale or modified manifest; publisher forgot to re-sign the pointer after editing the manifest; disk corruption in the state directory.
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
- durable capsule {} contracts blob digest mismatch
- installed WASM integrity check failed: expected BLAKE3 {expe
- durable capsule {id} WIT digest mismatch for {relative}
- durable capsule {id} manifest digest differs from authority
- durable capsule {id} content digest differs from authority r
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/936099baf2adf332.
Report an issue: GitHub.