micro-editor/micro · critical

Error creating configuration directory: %s

Error message

Error creating configuration directory: %s

What it means

Returned by InitConfigDir when os.MkdirAll(ConfigDir, os.ModePerm) fails while creating the micro configuration directory (including parents). The wrapped error (commonly 'permission denied' or 'not a directory') explains why the chosen config path cannot be materialized.

Source

Thrown at internal/config/config.go:48

		microHome = filepath.Join(xdgHome, "micro")
	}
	ConfigDir = microHome

	if len(flagConfigDir) > 0 {
		if _, err := os.Stat(flagConfigDir); os.IsNotExist(err) {
			e = errors.New("Error: " + flagConfigDir + " does not exist. Defaulting to " + ConfigDir + ".")
		} else {
			ConfigDir = flagConfigDir
			return nil
		}
	}

	// Create micro config home directory if it does not exist
	// This creates parent directories and does nothing if it already exists
	err := os.MkdirAll(ConfigDir, os.ModePerm)
	if err != nil {
		return errors.New("Error creating configuration directory: " + err.Error())
	}

	return e
}

View on GitHub (pinned to 1c8b82b32e)

Solutions

  1. Check the wrapped message: 'permission denied' -> fix ownership/perms (chown/chmod) on the parent path; 'not a directory' -> remove or rename the regular file blocking the path.
  2. Point micro somewhere writable: export MICRO_CONFIG_HOME=/home/$USER/.micro-config or XDG_CONFIG_HOME=$HOME/.config.
  3. On read-only-root containers, mount a writable volume over the config path.
  4. Free disk space / raise quota if the write failed due to ENOSPC.

Example fix

# before:
XDG_CONFIG_HOME=/etc/xdg micro   # /etc/xdg/micro cannot be created -> error

# after:
export XDG_CONFIG_HOME=$HOME/.config
micro
Defensive patterns

Strategy: fallback

Validate before calling

func writableDirFor(path string) bool {
    for p := path; ; p = filepath.Dir(p) {
        if fi, err := os.Stat(p); err == nil {
            return fi.IsDir() && p == path || fi.IsDir() // existing ancestor must be a dir
        }
        if p == "/" || p == "." {
            return false
        }
    }
}
// simplified: check ancestors are dirs and the target is creatable (os.MkdirAll in a temp-clone test)

Try / catch

if err := config.InitConfigDir(""); err != nil {
    if strings.HasPrefix(err.Error(), "Error creating configuration directory") {
        // retry with a writable location: os.Setenv("MICRO_CONFIG_HOME", "/tmp/micro-cfg")
        _ = config.InitConfigDir("")
    }
}

Prevention

When it happens

Trigger: ConfigDir resolving into a read-only location (/etc/micro with non-root user), a path component existing as a regular file (mkdir fails with ENOTDIR), SELinux/AppArmor denial, or full disk. Fires at internal/config/config.go:48.

Common situations: Setting XDG_CONFIG_HOME to a path on a read-only mount, a leftover regular file named 'micro' inside the chosen config parent, containers with read-only rootfs, or disk quota exhaustion.

Related errors


AI-assisted analysis of micro-editor/micro@1c8b82b32e (2026-08-15). Data as JSON: /api/errors/3cf691f4216175ae. Report an issue: GitHub.