astrid-runtime/astrid · error
legacy audit tree contains a redirect or boundary
Error message
legacy audit tree contains a redirect or boundary: {child} What it means
This error is thrown while validating a legacy audit tree directory. The validator walks the tree and refuses any child that is a symlink, resides on a different filesystem device than the root, or is itself a mountpoint, because such redirects/boundaries could make audit data escape the intended tree or be placed on untrusted storage. It is an InvalidData io::Error naming the offending child path.
Solutions
- Remove or replace the symlinked/mounted child with a real directory inside the same filesystem
- Move the audit tree entirely onto a single filesystem so no child crosses a device boundary
- Identify the offending path from the error message and unmount it (umount <child>) before retrying
- Restore the audit directory from backup as plain directories/files
Example fix
// before ln -s /mnt/big-disk/audit /var/lib/app/audit/events // after rm /var/lib/app/audit/events mkdir /var/lib/app/audit/events
Defensive patterns
Strategy: validation
Validate before calling
for entry in std::fs::read_dir(audit_root)? {
let p = entry?.path();
let md = std::fs::symlink_metadata(&p)?;
if md.file_type().is_symlink() { return Err(format!("symlink: {}", p.display())); }
} Type guard
fn is_plain_dir(md: &std::fs::Metadata) -> bool {
md.is_dir() && !md.file_type().is_symlink()
} Try / catch
match validate_audit_tree(root, root_dev) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData => eprintln!("fix audit tree: {e}"),
Err(e) => return Err(e),
Ok(()) => {},
} Prevention
- Never symlink directories inside the audit tree
- Keep the audit tree on a single filesystem; avoid submounts
- Monitor the tree with a cron check for symlinks/mountpoints
- Document the audit directory as managed state
When it happens
Trigger: Calling the audit-tree validation routine (e.g. when opening or migrating a legacy audit store) when any child entry of the tree is a symlink, has a different st_dev than the tree root, or is a mounted filesystem.
Common situations: Users replaced an audit log directory with a symlink to another disk; a subdirectory is a separate mount (e.g. tmpfs or NFS bind mount); container images where parts of the audit tree come from overlay mounts.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- legacy env/secret path is not a regular directory
- legacy principal-home entry is not a regular directory
- legacy principal-home root is not a directory
- legacy source is not a regular file
- workspace path must not contain redirects or unexpected…
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c2c370284e7291a8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:4347
}
if audit_tree_device(&metadata) != root_device || audit_mountpoint(path)? {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"legacy audit tree crosses a filesystem or mount boundary: {}",
path.display()
),
));
}
astrid_core::platform_fs::verify_no_redirects(path)?;
for entry in std::fs::read_dir(path)? {
let child = entry?.path();
let child_metadata = std::fs::symlink_metadata(&child)?;
if child_metadata.file_type().is_symlink()
|| audit_tree_device(&child_metadata) != root_device
|| audit_mountpoint(&child)?
{
return Err(std::io::Error::new(
std::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(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"legacy audit tree contains a special file: {}",
child.display()
),View on GitHub (pinned to affd8760f4)