astrid-runtime/astrid · critical
durable capsule {id} manifest digest differs from authority
Error message
durable capsule {id} manifest digest differs from authority receipt What it means
This error fires when digest_manifest(manifest_bytes) does not equal the manifest_digest recorded in the authority receipt. The authority receipt pins the exact bytes of the manifest it approved; a different digest means the manifest on disk was modified after signing, or the receipt belongs to a different manifest. The library refuses to load such a capsule because the approved manifest cannot be trusted.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:274
manifest_bytes: &[u8],
verification: &ArtifactVerification,
archive_files: &std::collections::BTreeMap<String, Vec<u8>>,
) -> anyhow::Result<()> {
if authority.schema_version != 1 {
bail!(
"durable capsule {id} has unsupported authority schema {}",
authority.schema_version
);
}
if authority.capsule_id != id || manifest.package.name != id {
bail!("durable capsule {id} identity differs across archive and authority");
}
if authority.version != manifest.package.version || metadata.version != authority.version {
bail!("durable capsule {id} version differs across package records");
}
let manifest_digest = crate::authority::digest_manifest(manifest_bytes);
if authority.manifest_digest != manifest_digest {
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");View on GitHub (pinned to affd8760f4)
Solutions
- Re-run the authority approval step to re-sign the current manifest bytes and update the receipt's manifest_digest.
- Restore the original signed manifest bytes that match the receipt (e.g. from the publish artifact or VCS).
- Reinstall the capsule from the originally published archive instead of a locally modified one.
- Ensure the build pipeline does not rewrite the manifest between approval and install.
Example fix
// before: editing the manifest after approval // manifest.capabilities.network added by hand -> digest differs from receipt // after: re-approve so the receipt covers the new bytes let manifest_bytes = serialize_manifest(&edited_manifest)?; let receipt = authority.approve(&manifest_bytes)?; // refreshes manifest_digest store.write_authority(owner, id, &receipt)?;
Defensive patterns
Strategy: validation
Validate before calling
let digest = crate::authority::digest_manifest(&manifest_bytes);
if digest != authority.manifest_digest {
// re-approve or restore original manifest before loading
} Type guard
fn manifest_is_approved(bytes: &[u8], a: &InstalledAuthority) -> bool {
crate::authority::digest_manifest(bytes) == a.manifest_digest
} Try / catch
match store.read_verified_durable_package_for_owner(owner, id) {
Ok(pkg) => pkg,
Err(e) if e.to_string().contains("manifest digest differs from authority receipt") => {
// restore signed manifest or re-run authority approval
authority.approve(&manifest_bytes)?;
store.read_verified_durable_package_for_owner(owner, id)?
}
Err(e) => return Err(e),
} Prevention
- Treat the manifest as immutable after authority approval; make changes via a republish flow.
- Disable build steps that reformat or regenerate the manifest between approval and install.
- Record and compare manifest digests in CI before deploying capsules.
- Keep the originally published archive as the single source for reinstalls.
When it happens
Trigger: read_verified_durable_package_for_owner loads an archive whose manifest bytes hash to something other than InstalledAuthority.manifest_digest — typically after editing CapsuleManifest fields (name, version, imports, exports, capabilities) without re-running the authority approval step.
Common situations: Hand-editing capsule.toml/manifest to tweak dependencies or permissions post-install; a build pipeline regenerating the manifest with different formatting/field order after approval; replaying an old authority receipt over a newly built archive.
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} content digest differs from authority r
- installed capsule identity/version differs from its authorit
- installed Capsule.toml differs from the exact manifest appro
- durable capsule {} contracts blob digest mismatch
- durable capsule {id} identity differs across archive and aut
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/50ff7054920846bb.
Report an issue: GitHub.