hashicorp/nomad · error

path was not a regular file

Error message

path was not a regular file

What it means

filepathIsRegular stats a candidate binary path and rejects anything that is not a plain regular file. Symbolic links that resolve to directories, sockets, FIFOs, or missing files surface here (stat errors pass through unchanged; this message is returned when the mode is not regular).

Source

Thrown at drivers/shared/executor/executor_linux_cgo.go:1103

	}

	// Turn relative-to-taskdir path into re-rooted absolute path to avoid
	// libcontainer trying to resolve the binary using $PATH.
	// Do *not* use filepath.Join as it will translate ".."s returned by
	// filepath.Rel. Prepending "/" will cause the path to be rooted in the
	// chroot which is the desired behavior.
	return filepath.Clean("/" + bin), hostPath, nil
}

// filepathIsRegular verifies that a filepath is a regular file (i.e. not a
// directory, socket, device, etc.)
func filepathIsRegular(path string) error {
	f, err := os.Stat(path)
	if err != nil {
		return err
	}
	if !f.Mode().Type().IsRegular() {
		return fmt.Errorf("path was not a regular file")
	}
	return nil
}

func newSetCPUSetCgroupHook(cgroupPath string) runc.Hook {
	return runc.NewFunctionHook(func(state *specs.State) error {
		return cgroups.WriteCgroupProc(cgroupPath, state.Pid)
	})
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Replace the non-regular file at the path with the actual executable binary
  2. Fix artifact/extract settings that produced a directory instead of a file
  3. Check symlink targets resolve to a regular executable file
  4. Verify the path referenced in the job spec points to the file, not its containing directory

Example fix

// before
bin/taskName/  <- directory extracted from artifact
// after
# correct the destination so the executable itself is at bin/taskName
Defensive patterns

Strategy: validation

Validate before calling

fi, err := os.Stat(candidateBin)
if err == nil && !fi.Mode().IsRegular() {
    return fmt.Errorf("%s is not a regular file", candidateBin)
}

Type guard

func isRegularFile(p string) bool {
    fi, err := os.Stat(p)
    return err == nil && fi.Mode().IsRegular()
}

Try / catch

if err != nil && strings.Contains(err.Error(), "not a regular file") {
    return fmt.Errorf("binary path points to a non-file (dir/socket?): %w", err)
}

Prevention

When it happens

Trigger: getPathInTaskDir or getPathInMount found a file matching the binary name, but os.Stat shows it is a directory, symlink-to-non-file, socket, or other special file instead of a regular executable.

Common situations: Artifact extraction created a directory with the binary's name; binary replaced by a symlink chain broken or pointing at a dir; task dir layout changed so the matched name is a folder; tmpfs/odd FS producing device files.

Related errors


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