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
- Remove the special file shown in the error from the capsule directory and re-inventory
- Fix the build/run step that creates FIFOs/sockets in the capsule output (write them to a temp dir instead)
- Repackage the capsule from a clean build output containing only regular files
- 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
- Keep runtime artifacts (sockets, FIFOs) out of capsule output dirs
- Clean build output before packaging
- Prune non-regular files in the packaging step
- Avoid packaging device or proc-like trees
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
- legacy audit tree contains a special file: {}
- legacy audit tree contains a special file: {child}
- capsule source is neither a directory nor a regular file: {}
- capsule materialization destination is not a directory
- capsule materialization destination already exists
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/89b9af35d827f3cb.
Report an issue: GitHub.