astrid-runtime/astrid · error
legacy principal-home entry crosses a filesystem boundary
Error message
legacy principal-home entry crosses a filesystem boundary: {principal_root} What it means
During the legacy principal-home audit migration, the kernel verifies that the principal root and everything under it (via audit_tree_device/st_dev comparison) lives on a single filesystem. If the legacy principal-home entry's device ID differs from the root filesystem's device, the rename-based migration could silently lose the atomicity and write-through guarantees it relies on, so the operation is refused with InvalidData.
Solutions
- Move the principal-home directory onto the same filesystem/mount as the root, then re-run the migration
- Remove any bind mounts or symlinks-to-other-mounts that place principal_root on another device
- If the split is intentional, migrate the audit data manually into migrations_dir/audit-principal-home.retired so the automatic migration is skipped
Example fix
// before: principal root on a separate mount /home/alice/.app/principal -> mounted tmpfs volume // after: keep the whole tree on one filesystem /home/alice/.app/principal (regular directory on the same device as root)
Defensive patterns
Strategy: validation
Validate before calling
use std::os::unix::fs::MetadataExt;
fn same_device(a: &std::path::Path, b: &std::path::Path) -> std::io::Result<bool> {
Ok(a.symlink_metadata()?.dev() == b.symlink_metadata()?.dev())
}
// call before migration:
// assert!(same_device(principal_root, &root)?) Type guard
fn is_real_dir(p: &std::path::Path) -> bool {
std::fs::symlink_metadata(p).map(|m| m.is_dir()).unwrap_or(false)
} Try / catch
match migrate_legacy_principal_home() {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData
&& e.to_string().contains("filesystem boundary") => {
eprintln!("move principal root onto one filesystem, then retry: {e}");
}
Err(e) => return Err(e),
Ok(()) => {}
} Prevention
- Keep the entire principal home on one filesystem; avoid bind mounts inside it
- Check `stat -c %d <path>` on the principal root and its parent before upgrading
- Document mount layout for machines running the migration
When it happens
Trigger: Calling the legacy principal-home migration path when the principal_root directory resides on a different mount point (different st_dev) than the filesystem root — e.g. the home directory is a separate mount, bind mount, or network share.
Common situations: Users whose home directories are automounted NFS volumes, separate /home partitions, or bind-mounted directories; containers where the principal root is a volume mount while the parent is on the container's overlay filesystem.
Related errors
- layout cutover record is empty
- layout cutover record is not a regular file
- legacy audit tree crosses a filesystem or mount boundary
- legacy capsule entry has a non-UTF-8 name
- legacy component source reappeared during ordinary…
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/16968c3cd1c0e8bc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:4152
};
let root_device = audit_tree_device(&metadata);
let mut default_source_present = false;
astrid_core::platform_fs::verify_no_redirects(&root)?;
for entry in std::fs::read_dir(&root)? {
let entry = entry?;
let principal_root = entry.path();
let principal_metadata = std::fs::symlink_metadata(&principal_root)?;
if principal_metadata.file_type().is_symlink() || !principal_metadata.is_dir() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"legacy principal-home entry is not a regular directory: {}",
principal_root.display()
),
));
}
if audit_tree_device(&principal_metadata) != root_device {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"legacy principal-home entry crosses a filesystem boundary: {}",
principal_root.display()
),
));
}
astrid_core::platform_fs::verify_no_redirects(&principal_root)?;
let local_root = principal_root.join(".local");
match std::fs::symlink_metadata(&local_root) {
Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"legacy principal .local path is not a directory: {}",
local_root.display()
),
));View on GitHub (pinned to affd8760f4)