hashicorp/nomad · error

path exists and is not directory - %s

Error message

path exists and is not directory - %s

What it means

CreateDirectory first stats the target path; if it exists and is a directory it succeeds, but if it exists as a regular file, symlink target, or otherwise non-directory entry, it returns this error rather than overwriting the path. It refuses to clobber existing non-directory files.

Source

Thrown at helper/winsvc/path_windows.go:63

	}

	return result.String(), nil
}

func (w *windowsPaths) CreateDirectory(path string, restrict_on_create bool) error {
	s, err := os.Stat(path)

	if err != nil && !errors.Is(err, os.ErrNotExist) {
		return err
	}

	if err == nil {
		// Directory exists so nothing to do
		if s.IsDir() {
			return nil
		}

		return fmt.Errorf("path exists and is not directory - %s", path)
	}

	// NOTE: mode ignored on Windows. If directory should
	// be restricted, an ACL will be applied below.
	if err := os.MkdirAll(path, 0o000); err != nil {
		return err
	}

	// Since the directory was just created, apply access
	// restrictions if requested
	if restrict_on_create {
		if err := setDirectoryPermissions(path); err != nil {
			return err
		}
	}

	return nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove or rename the conflicting file at the path, then retry CreateDirectory
  2. Point the service configuration at a different directory path
  3. If the file is expected data, migrate it into a proper directory layout first

Example fix

// before
os.WriteFile("C:\\ProgramData\\nomad\\data", blob, 0o644)
winsvc.CreateDirectory("C:\\ProgramData\\nomad\\data", 0o755) // conflict
// after
winsvc.CreateDirectory("C:\\ProgramData\\nomad\\data", 0o755) // create dir before any file use
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(path); err == nil && !fi.IsDir() {
	return fmt.Errorf("%s exists as a non-directory; remove or rename it first", path)
}
if err := winsvc.CreateDirectory(path, 0o755); err != nil {
	return err
}

Type guard

func isExistingDirectory(path string) bool {
	fi, err := os.Stat(path)
	return err == nil && fi.IsDir()
}

Try / catch

if err := winsvc.CreateDirectory(path, mode); err != nil {
	if strings.Contains(err.Error(), "path exists and is not directory") {
		if err := os.Rename(path, path+".bak"); err != nil {
			return err
		}
		return winsvc.CreateDirectory(path, mode)
	}
	return err
}

Prevention

When it happens

Trigger: Calling winsvc.CreateDirectory(path, mode) when a regular file (e.g. a stale data file or config) already exists at exactly `path`, so os.Stat succeeds with !s.IsDir().

Common situations: A previous run left a file where a directory is now required; a user manually placed a file at the configured data/alloc dir path; mount or volume shadowing the path with a file.

Related errors


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