astrid-runtime/astrid · critical

durable capsule {id} content digest differs from authority r

Error message

durable capsule {id} content digest differs from authority receipt

What it means

verify_package_identity throws this when the artifact verification's content digest (digest of the capsule's content/WASM payload) does not match the content_digest pinned in the authority receipt. The receipt records exactly which content the authority approved; any different content on disk is rejected. This prevents loading a swapped or rebuilt binary under an approved capsule identity.

Source

Thrown at crates/astrid-capsule-install/src/storage.rs:277

) -> 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");
    }
    if let Some(component) = manifest.components.first() {
        let Some(relative) = component.path.to_str() else {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Re-download or restore the original archive whose content matches the approved digest.
  2. Re-submit the new content to the authority for approval and replace the stored receipt with the new content_digest.
  3. Reinstall the capsule from the canonical published artifact rather than a locally rebuilt one.
  4. Verify archive integrity (checksum) after transfer to rule out corruption during copy.

Example fix

// before: rebuilt wasm swapped into approved archive
// authority.content_digest != blake3(component bytes)
// after: re-approve the rebuilt content
let verification = verify_artifact(&archive)?;
if authority.content_digest != verification.content_digest() {
    let receipt = authority.approve_content(&archive)?; // new content_digest
    store.write_authority(owner, id, &receipt)?;
}
Defensive patterns

Strategy: validation

Validate before calling

let verification = verify_artifact(&archive)?;
if verification.content_digest() != authority.content_digest {
    // content was replaced/rebuilt; re-approve or restore before loading
}

Type guard

fn content_is_approved(v: &ArtifactVerification, a: &InstalledAuthority) -> bool {
    v.content_digest() == a.content_digest
}

Try / catch

match store.read_verified_durable_package_for_owner(owner, id) {
    Ok(pkg) => pkg,
    Err(e) if e.to_string().contains("content digest differs from authority receipt") => {
        // fetch canonical archive and reinstall
        let archive = fetch_published(id, &version)?;
        store.install(owner, &archive)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: read_verified_durable_package_for_owner verifies the archive's artifact and gets ArtifactVerification::content_digest() != InstalledAuthority.content_digest — e.g. after rebuilding the WASM component, replacing files inside the archive, or associating the capsule with the wrong authority receipt.

Common situations: Rebuilding the wasm component with a different toolchain after the authority approved the original build; manually repacking the capsule archive; a corrupted/incomplete download or copy of the archive; two capsules' archives swapped in the install 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


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