astrid-runtime/astrid · error

capsule projection contains a special file: {}

Error message

capsule projection contains a special file: {}

What it means

This error means the projection inventory walk encountered a file that is neither a regular file nor a directory (e.g. a FIFO, device node, socket, or other special file). The kernel throws it because capsule projections must consist solely of ordinary files/directories; special files cannot be safely inventoried or projected and may hang reads or expose host devices.

Source

Thrown at crates/astrid-kernel/src/lib.rs:1651

                    anyhow::anyhow!("capsule projection path is not UTF-8: {}", path.display())
                })?;
                let metadata = std::fs::symlink_metadata(&path).map_err(|error| {
                    anyhow::anyhow!("inspect capsule projection {}: {error}", path.display())
                })?;
                let file_type = metadata.file_type();
                if file_type.is_symlink() {
                    anyhow::bail!(
                        "capsule projection contains a symbolic link: {}",
                        path.display()
                    );
                }
                if file_type.is_dir() {
                    inventory.directories.insert(relative_text.to_owned());
                    walk(root, &path, inventory)?;
                } else if file_type.is_file() {
                    inventory.files.insert(relative_text.to_owned());
                } else {
                    anyhow::bail!(
                        "capsule projection contains a special file: {}",
                        path.display()
                    );
                }
            }
            Ok(())
        }

        let mut inventory = ProjectionInventory::default();
        walk(root, root, &mut inventory)?;
        Ok(inventory)
    }

    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
    fn read_projection_file_nofollow(path: &Path) -> anyhow::Result<Vec<u8>> {
        use std::io::Read as _;

        let metadata = std::fs::symlink_metadata(path).map_err(|error| {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Remove the special file shown in the error from the capsule directory and re-inventory
  2. Fix the build/run step that creates FIFOs/sockets in the capsule output (write them to a temp dir instead)
  3. Repackage the capsule from a clean build output containing only regular files
  4. Investigate any process still writing into the materialized capsule directory and stop it before activation

Example fix

# before: build leaves a socket in the output
my-server --socket build/capsule.sock

# after: keep runtime artifacts out of the capsule output
my-server --socket /tmp/app.sock
Defensive patterns

Strategy: validation

Validate before calling

let ft = std::fs::symlink_metadata(p)?.file_type();
if !(ft.is_file() || ft.is_dir()) {
    return Err(format!("special file in capsule output: {}", p.display()));
}

Try / catch

match result {
    Err(e) if e.to_string().contains("special file") => {
        // remove the FIFO/socket/device node and rebuild
    }
    other => other?,
}

Prevention

When it happens

Trigger: The recursive inventory walk (walk over the materialized capsule directory) hits a directory entry whose symlink_metadata file type is neither file nor dir — e.g. a named pipe or unix socket created inside the capsule directory by a build step or a process writing into the projection.

Common situations: A build tool creating FIFOs/sockets in the output directory before packaging; a dev server writing a .sock file into the capsule dir; packaging /dev-like trees; an archive that contained device nodes and was extracted with privileges.

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/89b9af35d827f3cb. Report an issue: GitHub.