hashicorp/nomad · error

cannot create configuration directory - %s

Error message

cannot create configuration directory - %s

What it means

After expanding paths, configInstall calls c.winPaths.CreateDirectory(opts.configDir, true) to ensure the configuration directory exists. This error wraps any failure from that creation — permission denied, invalid path, or an existing file conflicting with the directory name.

Source

Thrown at command/windows_service_install.go:266

	// If the config or data directory are unset, default them
	if opts.configDir == "" {
		opts.configDir = filepath.Join(winsvc.WINDOWS_INSTALL_APPDATA_DIRECTORY, "config")
	}
	if opts.dataDir == "" {
		opts.dataDir = filepath.Join(winsvc.WINDOWS_INSTALL_APPDATA_DIRECTORY, "data")
	}

	var err error
	if opts.configDir, err = c.winPaths.Expand(opts.configDir); err != nil {
		return fmt.Errorf("cannot generate configuration path - %s", err)
	}
	if opts.dataDir, err = c.winPaths.Expand(opts.dataDir); err != nil {
		return fmt.Errorf("cannot generate data path - %s", err)
	}

	// Ensure directories exist
	if err = c.winPaths.CreateDirectory(opts.configDir, true); err != nil {
		return fmt.Errorf("cannot create configuration directory - %s", err)
	}

	if err = c.winPaths.CreateDirectory(opts.dataDir, true); err != nil {
		return fmt.Errorf("cannot create data directory - %s", err)
	}

	// Check if any configuration files exist
	matches, _ := filepath.Glob(filepath.Join(opts.configDir, "*"))
	if len(matches) < 1 {
		f, err := os.Create(filepath.Join(opts.configDir, "config.hcl"))
		if err != nil {
			return fmt.Errorf("could not create default configuration file - %s", err)
		}
		fmt.Fprintf(f, strings.TrimSpace(`
# Full configuration options can be found at https://developer.hashicorp.com/nomad/docs/configuration

data_dir  = "%s"
bind_addr = "0.0.0.0"

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Run the install command from an elevated (Administrator) prompt
  2. Choose a writable location such as C:\ProgramData\nomad as -config-dir
  3. Check whether a file (not a directory) already exists at the target path and remove/rename it
  4. Verify the drive/volume is present and writable

Example fix

// before (non-elevated shell)
nomad windows service install -config-dir "C:\Windows\System32\nomad"
// after (elevated, writable location)
nomad windows service install -config-dir "C:\ProgramData\nomad"
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: parent of configDir writable and target not an existing file
if fi, err := os.Stat(configDir); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s exists and is not a directory", configDir)
}
if err := os.MkdirAll(filepath.Dir(configDir), 0o755); err != nil {
    return fmt.Errorf("parent not writable: %w", err)
}

Prevention

When it happens

Trigger: Running 'nomad windows service install' when the expanded configDir cannot be created: no write permission at the parent (e.g. Program Files without elevation), a file already exists at the configDir path, or the path is on an unavailable drive.

Common situations: Installing without Administrator rights; config-dir pointing inside a read-only location; a previous botched install left a regular file named like the directory; network drive not reachable at install time.

Related errors


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