astrid-runtime/astrid · error
legacy audit tree contains a special file: {}
Error message
legacy audit tree contains a special file: {} What it means
The legacy audit tree may contain only directories and regular files. When validate_audit_tree's recursion encounters a child that is neither (fifo, socket, device node, etc.), it aborts with InvalidData. Special files can block or hijack deletion/renaming and indicate a layout the migration barrier does not admit.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:552
let child_metadata = fs::symlink_metadata(&child).map_err(io::Error::other)?;
if child_metadata.file_type().is_symlink()
|| device_id(&child_metadata) != root_device
|| active_mountpoint(&child)?
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit tree contains a redirect or boundary: {}",
child.display()
),
));
}
if child_metadata.is_dir() {
validate_audit_tree(&child, root_device)?;
} else if child_metadata.is_file() {
astrid_core::platform_fs::verify_no_redirects(&child)?;
} else {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit tree contains a special file: {}",
child.display()
),
));
}
}
Ok(())
}
#[cfg(not(unix))]
fn delete_audit_tree(path: &Path, root_device: u64) -> io::Result<()> {
validate_audit_tree(path, root_device)?;
for entry in fs::read_dir(path).map_err(io::Error::other)? {
let child = entry.map_err(io::Error::other)?.path();
let metadata = fs::symlink_metadata(&child).map_err(io::Error::other)?;
if metadata.is_dir() {View on GitHub (pinned to affd8760f4)
Solutions
- Stop the process using the fifo/socket inside the audit tree and remove the special file.
- Move any still-needed special file out of the audit directory to a runtime location (e.g. /run).
- Re-run migration once the tree holds only regular files and directories.
Example fix
// before srwxr-xr-x audit.sock in ~/.astrid/principal/audit/ // after mv ~/.astrid/principal/audit/audit.sock /run/myapp/audit.sock # or: rm ~/.astrid/principal/audit/audit.sock
Defensive patterns
Strategy: validation
Validate before calling
fn no_special_files(root: &Path) -> std::io::Result<bool> {
for entry in std::fs::read_dir(root)? {
let m = std::fs::symlink_metadata(entry?.path())?;
if !m.is_dir() && !m.is_file() { return Ok(false); }
}
Ok(true)
} Try / catch
if let Err(e) = migrate_legacy_audit(&home, &source) {
if e.to_string().contains("special file") {
// remove/relocate the named fifo/socket/device and retry
}
} Prevention
- Keep sockets and fifos in /run or another runtime dir, never in audit data.
- Scan with `find <audit-dir> ! -type f ! -type d` before migrating.
- Stop legacy daemons that create special files in the audit path.
When it happens
Trigger: Retiring, preflighting, or deleting an audit tree that contains a fifo (named pipe), unix socket, or device node among its entries; the else-branch of the per-child check fires.
Common situations: An application once wrote its socket or pipe into the audit directory; leftover mkfifo test artifacts; device nodes created by misconfigured tooling.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- capsule projection contains a special file: {}
- layout migration source contains a special file: {}
- legacy principal-home root is not a directory: {}
- legacy principal-home entry is not a regular directory: {}
- legacy source contains a special entry: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/eb0fa867f8858f55.
Report an issue: GitHub.