astrid-runtime/astrid · error

durable capsule archive contains an unsupported entry

Error message

durable capsule archive contains an unsupported entry

What it means

After allowing directories and regular files, any remaining tar entry type (e.g. GNU sparse, contiguous, or other exotic entry types) is rejected with this error. The materializer only implements safe handling for plain files and directories, so anything else aborts extraction.

Solutions

  1. Rebuild the archive using the library's canonical_capsule_archive so only standard file/dir entries exist.
  2. Re-create the tar with standard settings (no --sparse, no unusual formats) if packing manually.
  3. Verify the archive with artifact::verify_archive_bytes to detect corruption before materializing.

Example fix

// before
tar --sparse -cvf capsule.tar components
// after
rm capsule.tar && tar -cvf capsule.tar components
Defensive patterns

Strategy: try-catch

Validate before calling

for entry in tar::Archive::new(&bytes[..]).entries()? {
    let t = entry?.header().entry_type();
    if !(t.is_file() || t.is_dir()) {
        anyhow::bail!("unsupported entry type {:?} — rebuild archive", t);
    }
}

Try / catch

match materialize_capsule_package(&pkg, &dest) {
    Err(e) if e.to_string().contains("unsupported entry") => {
        warn!("archive used exotic tar entry types; rebuilding canonically");
        rebuild_canonical_archive(&src_dir)?;
        materialize_capsule_package(&pkg, &dest)?;
    }
    other => other,
}

Prevention

When it happens

Trigger: Materializing an archive with a non-file, non-dir entry type that is also not a link/special file — e.g. GNU long-name/sparse metadata entries created by an unusual tar implementation, or a corrupted header whose type flag is invalid.

Common situations: Archives produced by non-GNU or exotic tar variants; archives transferred through something that mangled headers; a partially rewritten/tampered archive with a garbage typeflag byte.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        if !names.insert(relative.clone()) {
            bail!("durable capsule archive contains duplicate path");
        }
        let output = destination.join(&relative);
        if entry.header().entry_type().is_symlink()
            || entry.header().entry_type().is_hard_link()
            || entry.header().entry_type().is_block_special()
            || entry.header().entry_type().is_character_special()
            || entry.header().entry_type().is_fifo()
        {
            bail!("durable capsule archive contains a link or special file");
        }
        if entry.header().entry_type().is_dir() {
            fs::create_dir_all(&output)
                .with_context(|| format!("create materialized directory {}", output.display()))?;
            continue;
        }
        if !entry.header().entry_type().is_file() {
            bail!("durable capsule archive contains an unsupported entry");
        }
        if let Some(parent) = output.parent() {
            fs::create_dir_all(parent)
                .with_context(|| format!("create materialized parent {}", parent.display()))?;
            reject_symlink_ancestors(destination, parent)?;
        }
        let mut bytes = Vec::new();
        entry
            .read_to_end(&mut bytes)
            .context("read durable capsule archive file")?;
        fs::write(&output, bytes)
            .with_context(|| format!("write materialized file {}", output.display()))?;
    }
    fs::write(destination.join("meta.json"), &package.metadata)
        .context("write materialized capsule metadata")?;
    fs::write(destination.join("authority.json"), &package.authority)
        .context("write materialized capsule authority")?;
    Ok(())

View on GitHub (pinned to affd8760f4)