hashicorp/nomad · error

unable to read rooted allocation directory

Error message

unable to read rooted allocation directory

What it means

During artifact sandboxing, mergeDirectories walks a source directory of the rooted allocation directory by reading its entries. When the io/fs filesystem backing the rooted alloc dir does not implement fs.ReadDirFS (only file reading), the type assertion at.FS().(fs.ReadDirFS) fails and this error is returned: 'unable to read rooted allocation directory'. It means Nomad cannot enumerate directory entries, so directories cannot be merged into the task sandbox.

Source

Thrown at client/allocrunner/taskrunner/getter/util.go:365

// the dstDir. This is a destructive action; the contents of
// srcDir are moved into dstDir.
func mergeDirectories(at *os.Root, srcDir, dstDir string) error {
	var entries []fs.DirEntry
	var err error
	if runtime.GOOS == "windows" {
		dirFile, err := at.Open(srcDir)
		if err != nil {
			return err
		}
		defer dirFile.Close()
		entries, err = dirFile.ReadDir(-1)
		if err != nil {
			return err
		}
	} else {
		rd, ok := at.FS().(fs.ReadDirFS)
		if !ok {
			return errors.New("unable to read rooted allocation directory")
		}
		entries, err = rd.ReadDir(srcDir)
	}
	if err != nil {
		return err
	}

	for _, entry := range entries {
		src := filepath.Join(srcDir, entry.Name())
		dst := filepath.Join(dstDir, entry.Name())

		srcInfo, err := at.Stat(src)
		if err != nil {
			return err
		}

		dstInfo, err := at.Stat(dst)
		if err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check host filesystem for client data_dir/alloc dir: run on a filesystem supporting normal readdir (local ext4/xfs); fix restrictive mount options or permissions
  2. Verify the Nomad client user can read (r+x) the rooted alloc directory: chown/adjust permissions and restart the client
  3. Remove stale/corrupt alloc directories under data_dir/alloc and let the client re-create them
  4. If it persists, upgrade Nomad or file an issue — the fstype backing the alloc dir may not implement ReadDirFS on your platform

Example fix

# before: data_dir on a mount without directory read support for the client user
client { data_dir = "/mnt/restricted-fs/nomad" }
# after: local filesystem with correct ownership
client { data_dir = "/opt/nomad/data" }
sudo chown -R nomad:nomad /opt/nomad/data
Defensive patterns

Strategy: validation

Validate before calling

// Go: verify the FS backing the alloc dir supports ReadDir before merging
if _, ok := at.FS().(fs.ReadDirFS); !ok {
	return errors.New("alloc dir fstype cannot list directories; check client data_dir filesystem")
}

Type guard

func canReadDir(fsys fs.FS) bool {
	_, ok := fsys.(fs.ReadDirFS)
	return ok
}

Try / catch

if err := mergeDirectories(src, dst); err != nil {
	if strings.Contains(err.Error(), "unable to read rooted allocation directory") {
		// check client data_dir filesystem/permissions, then re-run task
		return fmt.Errorf("alloc dir unreadable (fstype/permissions): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Running the getter's runCmd path where mergeDirectories is invoked with a srcDir that must be listed, and the mounted fstype used for the rooted allocation directory lacks a ReadDir method (assertion in util.go:365 fails). Typically caused by an unusual/misconfigured filesystem for client dataDir or alloc mount, or a platform/OS-level limitation of the fstype in use.

Common situations: Nomad clients running on filesystems or mount options where directory listing on the alloc dir is restricted (e.g. certain overlay/network filesystems, permission fixes on client data_dir), or nonstandard client data_dir configuration. Permissions on the alloc dir can also surface as this failure path in some setups.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/97277495e5fd7d33. Report an issue: GitHub.