astrid-runtime/astrid · error

durable capsule registry is unavailable

Error message

durable capsule registry is unavailable

What it means

During materialization verification the kernel's principal_store (the durable capsule registry) is None, so the verified package cannot be read at all. verify_published_materialization requires the durable registry to confirm what was published; without it, verification cannot proceed and fails with this error.

Solutions

  1. Initialize and attach the principal_store (durable capsule registry) when constructing the kernel
  2. Check kernel startup logs for registry initialization failures and fix the storage backend
  3. Re-run materialization repair/confirm after the registry is available
  4. Ensure the deployment config enables the durable registry rather than a registry-less mode

Example fix

// before
let kernel = Kernel::new(dir, principal_directory, None)?;
// after
let kernel = Kernel::new(dir, principal_directory, Some(principal_store))?;
Defensive patterns

Strategy: validation

Validate before calling

if kernel.principal_store().is_none() {
    return Err("durable capsule registry not configured; materialization verification unavailable");
}

Type guard

fn registry_ready(kernel: &Kernel) -> bool {
    kernel.principal_store().is_some()
}

Try / catch

match kernel.verify_published_materialization(...) {
    Err(e) if e.to_string().contains("durable capsule registry is unavailable") => {
        eprintln!("kernel misconfigured: enable the durable registry");
    }
    other => other?,
}

Prevention

When it happens

Trigger: verify_published_materialization() reaches read_verified_durable_package_for_owner while self.principal_store is None — the kernel was constructed without a durable capsule registry backing store.

Common situations: Kernel started in a reduced/test configuration without the durable registry; registry initialization failed at startup and was left as None; embedding the kernel library without wiring the principal store.

Related errors


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

Appendix: source

Thrown at crates/astrid-kernel/src/capsule_materialization.rs:25

impl Kernel {
    /// Verify every projected byte against one immutable package snapshot.
    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
    pub(crate) fn verify_published_materialization(
        &self,
        dir: &Path,
        principal: &astrid_core::principal::PrincipalId,
        manifest: &astrid_capsule_types::manifest::CapsuleManifest,
        snapshot: &astrid_storage::CapsulePackageSnapshot,
    ) -> anyhow::Result<()> {
        self.validate_published_cache_path(dir, principal, manifest, snapshot)?;
        let uid = self
            .principal_directory
            .uid_for(principal)
            .map_err(|error| anyhow::anyhow!("resolve capsule cache owner UID: {error}"))?;
        let verified = astrid_capsule_install::read_verified_durable_package_for_owner(
            self.principal_store
                .as_ref()
                .ok_or_else(|| anyhow::anyhow!("durable capsule registry is unavailable"))?,
            &astrid_storage::StateOwner::Principal(uid),
            manifest.package.name.as_str(),
        )?
        .ok_or_else(|| anyhow::anyhow!("materialized capsule is absent from durable registry"))?;
        if verified.snapshot() != snapshot {
            anyhow::bail!("materialized capsule snapshot differs from the caller's publication");
        }
        if verified.manifest().package.name != manifest.package.name
            || verified.manifest().package.version != manifest.package.version
        {
            anyhow::bail!("materialized capsule manifest differs from durable registry");
        }
        let manifest_bytes = Self::read_projection_file_nofollow(&dir.join("Capsule.toml"))
            .map_err(|error| anyhow::anyhow!("read materialized capsule manifest: {error:#}"))?;
        if manifest_bytes != verified.manifest_bytes() {
            anyhow::bail!("durable capsule manifest bytes do not match materialization");
        }
        let metadata_bytes = Self::read_projection_file_nofollow(&dir.join("meta.json"))

View on GitHub (pinned to affd8760f4)