hashicorp/nomad · error
failed to Statfs %q: %v
Error message
failed to Statfs %q: %v
What it means
IsNSorErr validates that a path refers to a namespace file by statfs-ing it and comparing the filesystem magic (PROCFS_MAGIC or NSFS_MAGIC). This error is returned when syscall.Statfs fails on the given path and the path exists — i.e. Statfs failed for a reason other than non-existence, so the path cannot be confirmed as a namespace.
Source
Thrown at client/lib/nsutil/ns_linux.go:131
NSFS_MAGIC = unix.NSFS_MAGIC
PROCFS_MAGIC = unix.PROC_SUPER_MAGIC
)
type NSPathNotExistErr struct{ msg string }
func (e NSPathNotExistErr) Error() string { return e.msg }
type NSPathNotNSErr struct{ msg string }
func (e NSPathNotNSErr) Error() string { return e.msg }
func IsNSorErr(nspath string) error {
stat := syscall.Statfs_t{}
if err := syscall.Statfs(nspath, &stat); err != nil {
if os.IsNotExist(err) {
err = NSPathNotExistErr{msg: fmt.Sprintf("failed to Statfs %q: %v", nspath, err)}
} else {
err = fmt.Errorf("failed to Statfs %q: %v", nspath, err)
}
return err
}
switch stat.Type {
case PROCFS_MAGIC, NSFS_MAGIC:
return nil
default:
return NSPathNotNSErr{msg: fmt.Sprintf("unknown FS magic on %q: %x", nspath, stat.Type)}
}
}
// GetNS returns an object representing the namespace referred to by @path
func GetNS(nspath string) (NetNS, error) {
err := IsNSorErr(nspath)
if err != nil {
return nil, err
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Check the wrapped errno from the %v: EACCES means fix permissions, ENOTDIR/ENOENT means fix the path
- Verify /proc is mounted and readable by the calling user
- Confirm the path is the correct /proc/<pid>/ns/net or a valid bind mount of a namespace
- If os.IsNotExist was the cause, the error would be NSPathNotExistErr instead — treat this variant as an environment/mount problem
Example fix
// before
ns, err := GetNS("/proc/9999/ns/net") // pid gone, statfs fails
// after
if _, err := os.Stat("/proc/9999/ns/net"); err != nil {
return fmt.Errorf("netns path unavailable: %w", err)
}
ns, err := GetNS("/proc/9999/ns/net") Defensive patterns
Strategy: validation
Validate before calling
func validateNSPath(p string) error {
fi, err := os.Stat(p)
if err != nil {
return fmt.Errorf("netns path missing: %w", err)
}
if !fi.Mode().IsRegular() && fi.Mode()&os.ModeDevice == 0 && !fi.Mode().IsDir() {
// proceed; ns files are odd modes, only reject obvious dirs
_ = fi
}
return nil
} Type guard
func isNSPathNotExistErr(err error) bool {
_, ok := err.(NSPathNotExistErr)
return ok
} Try / catch
if err := IsNSorErr(nspath); err != nil {
if isNSPathNotExistErr(err) {
return fmt.Errorf("netns does not exist: %w", err)
}
return fmt.Errorf("netns path unusable (check /proc mount & perms): %w", err)
} Prevention
- Verify /proc is mounted and readable before resolving ns paths
- Re-check that the PID owning the namespace is alive
- Use canonical paths (/proc/<pid>/ns/net) and fresh bind mounts
- Handle NSPathNotExistErr separately from generic Statfs failures
When it happens
Trigger: Calling IsNSorErr (directly or via GetNS) with a path that exists but cannot be stat'd: permission denied on a parent directory, path is on a broken mount, I/O error, or too many symbolic links.
Common situations: Passing a netns path like /proc/<pid>/ns/net where /proc is not mounted or is mounted with hidepid restrictions; stale bind-mounted ns paths after a container exited (though those usually give NSPathNotExistErr); typo in the path with a dangling mount point.
Related errors
- failed to remove ns path %s: %w
- Couldn't change owner/group of %v to (uid: %v, gid: %v): %w
- Couldn't resolve symlink for %v: %w
- Failed to delete proc directory %q: %w
- failed to open %s: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/f7a21fa4aba1d968.
Report an issue: GitHub.