astrid-runtime/astrid · error
durable capsule {id} metadata executable hash differs from a
Error message
durable capsule {id} metadata executable hash differs from authority receipt What it means
verify_package_identity checks that, when the authority receipt pins a WASM hash (wasm_hash_pinned), the wasm_hash recorded in the capsule metadata equals the authority's approved_wasm_hash. This bail fires when the metadata's executable hash disagrees with the approved hash, i.e. the metadata references an executable that was never approved by the authority. It guards against installing a capsule whose metadata claims a different binary than the one the authority signed off on.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:292
bail!("durable capsule {id} manifest digest differs from authority receipt");
}
if authority.content_digest != verification.content_digest() {
bail!("durable capsule {id} content digest differs from authority receipt");
}
let expected_imports = crate::wit::version_map_to_strings(&manifest.imports, |definition| {
definition.version.to_string()
});
if metadata.imports != expected_imports {
bail!("durable capsule {id} imports differ between metadata and archive");
}
let expected_exports = crate::wit::version_map_to_strings(&manifest.exports, |definition| {
definition.version.to_string()
});
if metadata.exports != expected_exports {
bail!("durable capsule {id} exports differ between metadata and archive");
}
if authority.wasm_hash_pinned && metadata.wasm_hash != authority.approved_wasm_hash {
bail!("durable capsule {id} metadata executable hash differs from authority receipt");
}
if let Some(component) = manifest.components.first() {
let Some(relative) = component.path.to_str() else {
bail!("durable capsule {id} component path is not UTF-8");
};
let Some(bytes) = archive_files.get(relative) else {
bail!("durable capsule {id} component is missing from its archive");
};
if Path::new(relative)
.extension()
.is_some_and(|extension| extension.eq_ignore_ascii_case("wasm"))
{
let archive_hash = blake3::hash(bytes).to_hex().to_string();
if authority.wasm_hash_pinned
&& authority.approved_wasm_hash.as_deref() != Some(archive_hash.as_str())
{
bail!("durable capsule {id} WASM hash differs between authority and archive");
}View on GitHub (pinned to affd8760f4)
Solutions
- Obtain a new authority receipt whose approved_wasm_hash matches the metadata's wasm_hash (re-approval of the rebuilt component).
- Install the exact capsule build the authority approved, so metadata.wasm_hash equals approved_wasm_hash.
- If the pin is no longer wanted, have the authority re-issue the receipt without a pinned WASM hash (wasm_hash_pinned = false).
- Print both hashes (metadata.wasm_hash vs authority.approved_wasm_hash) to confirm which build is stale.
Example fix
// before: rebuilt wasm, stale receipt assert_ne!(metadata.wasm_hash, authority.approved_wasm_hash); // after: refresh the authority receipt for the new build let authority = request_approval(&new_build); // approved_wasm_hash == metadata.wasm_hash install_with_authority(&package, &authority);
Defensive patterns
Strategy: validation
Validate before calling
if authority.wasm_hash_pinned && metadata.wasm_hash != authority.approved_wasm_hash {
return Err(anyhow!("metadata hash {:?} not approved (receipt: {:?})", metadata.wasm_hash, authority.approved_wasm_hash));
} Prevention
- Re-issue the authority receipt whenever the component is rebuilt.
- Pin capsule versions to receipts and never mix builds from different versions.
- Log both hashes on mismatch to identify the stale artifact quickly.
When it happens
Trigger: Calling read_verified_durable_package_for_owner on a capsule where authority.wasm_hash_pinned is true and metadata.wasm_hash != authority.approved_wasm_hash — e.g. metadata was regenerated for a rebuilt component while the authority receipt still pins the previously approved hash.
Common situations: Recompiling the WASM component after approval (new blake3 hash) but keeping the old authority receipt; pointing an install at a newer capsule version than the one the authority approved; copying metadata from another capsule build; hand-editing the wasm_hash field.
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 {id} WASM hash differs between authority and
- durable capsule {id} exports differ between metadata and arc
- cannot remove capsule authority while an install transaction
- an incomplete capsule authority update exists at {}; remove
- unsupported installed authority schema {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/9de59376083081f4.
Report an issue: GitHub.