astrid-runtime/astrid · error
legacy audit tree contains a redirect or boundary: {}
Error message
legacy audit tree contains a redirect or boundary: {} What it means
While recursively validating the legacy audit tree, validate_audit_tree inspects each child with symlink_metadata and rejects any child that is a symlink, lives on a different device, or is an active mountpoint. This prevents redirected or cross-filesystem entries from being swept into the rename/delete, which could affect data outside the legacy audit layout.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:539
}
if device_id(&metadata) != root_device || active_mountpoint(path)? {
return Err(io::Error::new(
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 fs::read_dir(path).map_err(io::Error::other)? {
let child = entry.map_err(io::Error::other)?.path();
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()
),View on GitHub (pinned to affd8760f4)
Solutions
- Replace symlinks inside the audit tree with real copies of the target data (cp -L then remove the link).
- Unmount any mount covering entries inside the audit tree.
- Move cross-device entries onto the same filesystem as the audit root, or delete them if unneeded.
Example fix
// before current.log -> /var/log/audit/current.log (symlink) // after cp -L /var/log/audit/current.log ~/.astrid/principal/audit/current.log rm ~/.astrid/principal/audit/current.log # remove symlink, keep the copy
Defensive patterns
Strategy: validation
Validate before calling
fn children_are_plain(root: &Path) -> std::io::Result<bool> {
use std::os::unix::fs::MetadataExt;
let root_dev = std::fs::symlink_metadata(root)?.dev();
for entry in std::fs::read_dir(root)? {
let m = std::fs::symlink_metadata(entry?.path())?;
if m.file_type().is_symlink() || m.dev() != root_dev { return Ok(false); }
}
Ok(true)
} Try / catch
if let Err(e) = migrate_legacy_audit(&home, &source) {
if e.to_string().contains("contains a redirect or boundary") {
// the message names the offending child; fix that entry and retry
}
} Prevention
- Copy (cp -L) instead of linking files into the audit tree.
- Audit for symlinks with `find <audit-dir> -type l` pre-migration.
- Avoid per-subdirectory mounts inside legacy trees.
When it happens
Trigger: Retiring or preflighting an audit tree that contains a symlinked file/subdirectory, a bind-mounted child, or any entry on another device — detected during the recursive read_dir descent.
Common situations: Symlinked log or artifact files inside the audit directory pointing elsewhere; per-directory mounts; container bind mounts over subdirectories.
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
- leftover capsule authority receipt is not a regular file: {}
- legacy capsule authority root is not a regular directory: {}
- legacy capsule authority root contains a non-regular entry:
- legacy capsule authority root is not a regular directory: {}
- directory symlink {} not allowed in capsule source tree (ref
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/80d40dfa91aa5288.
Report an issue: GitHub.