hashicorp/nomad · critical

failed to change directory permissions for the AllocDir: %v

Error message

failed to change directory permissions for the AllocDir: %v

What it means

For the temp-based alloc dir, the client changes permissions with os.Chmod(p, 0o711) so the execute bit is present for traversal. If the chmod fails, init aborts with this error. Without the execute bit, task drivers cannot traverse the alloc directory.

Source

Thrown at client/client.go:759

	if conf.AllocDir != "" {
		if err := os.MkdirAll(conf.AllocDir, 0o711); err != nil {
			return fmt.Errorf("failed creating alloc dir: %w", err)
		}
	} else {
		// Otherwise make a temp directory to use.
		p, err := os.MkdirTemp("", "NomadClient")
		if err != nil {
			return fmt.Errorf("failed creating temporary directory for the AllocDir: %v", err)
		}

		p, err = filepath.EvalSymlinks(p)
		if err != nil {
			return fmt.Errorf("failed to find temporary directory for the AllocDir: %v", err)
		}

		// Change the permissions to have the execute bit
		if err := os.Chmod(p, 0o711); err != nil {
			return fmt.Errorf("failed to change directory permissions for the AllocDir: %v", err)
		}

		conf = c.UpdateConfig(func(c *config.Config) {
			c.AllocDir = p
			c.AllocMountsDir = p
		})
	}

	c.logger.Info("using alloc directory", "alloc_dir", conf.AllocDir)

	reserved := "<none>"
	if conf.Node != nil && conf.Node.ReservedResources != nil {
		// Node should always be non-nil due to initialization in the
		// agent package, but don't risk a panic just for a long line.
		reserved = conf.Node.ReservedResources.Networks.ReservedHostPorts
	}
	c.logger.Info("using dynamic ports",
		"min", conf.MinDynamicPort,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Place the alloc dir (or TMPDIR) on a local POSIX filesystem that supports permission changes instead of NFS/CIFS/fuse.
  2. Check the wrapped error (EPERM typically) and ensure the process user owns the directory.
  3. Configure an explicit alloc_dir on supported storage to skip the temp-dir/chmod path.

Example fix

// before: TMPDIR on CIFS mount
Environment=TMPDIR=/mnt/cifs/tmp
// after
client { alloc_dir = "/var/lib/nomad/alloc" }  # local ext4 volume
Defensive patterns

Strategy: validation

Validate before calling

d, err := os.MkdirTemp(os.TempDir(), "NomadClientProbe")
if err != nil { return err }
if err := os.Chmod(d, 0o711); err != nil {
    os.Remove(d)
    return fmt.Errorf("temp filesystem %q does not support chmod: %v", os.TempDir(), err)
}
os.Remove(d)

Try / catch

if err := clientInit(); err != nil {
    if strings.Contains(err.Error(), "failed to change directory permissions for the AllocDir") {
        // move TMPDIR/alloc_dir to a local POSIX filesystem
    }
}

Prevention

When it happens

Trigger: client init without alloc_dir configured: os.Chmod(tempAllocDir, 0o711) returns error right after MkdirTemp/EvalSymlinks.

Common situations: Filesystem that does not support chmod (some network/CIFS/NFS mounts, certain fuse mounts), or ownership of the temp dir unexpectedly changed between creation and chmod (external cleaner/tampering).

Related errors


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