GoogleContainerTools/skaffold · error

creating parent directory: %w

Error message

creating parent directory: %w

What it means

VerifyOrCreateFile ensures the Skaffold config file exists, creating it (and its parents) if missing; this error wraps a failure of os.MkdirAll on the path's parent directory. MkdirAll fails when a component of the parent path exists as a non-directory, the process lacks write permission on an ancestor, or the filesystem is read-only. Called from ResolveConfigFile when bootstrapping the default skaffold config location.

Source

Thrown at pkg/skaffold/util/util.go:130

}

func Ptr[T any](t T) *T {
	o := t
	return &o
}

func IsURL(s string) bool {
	return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}

// VerifyOrCreateFile checks if a file exists at the given path,
// and if not, creates all parent directories and creates the file.
func VerifyOrCreateFile(path string) error {
	_, err := os.Stat(path)
	if err != nil && os.IsNotExist(err) {
		dir := filepath.Dir(path)
		if err = os.MkdirAll(dir, 0744); err != nil {
			return fmt.Errorf("creating parent directory: %w", err)
		}
		if _, err = os.Create(path); err != nil {
			return fmt.Errorf("creating file: %w", err)
		}
		return nil
	}
	return err
}

// Expand replaces placeholders for a given key with a given value.
// It supports the ${key} and the $key syntax.
func Expand(text, key, value string) string {
	text = strings.ReplaceAll(text, "${"+key+"}", value)

	indices := regexp.MustCompile(`\$`+key).FindAllStringIndex(text, -1)

	for i := len(indices) - 1; i >= 0; i-- {
		from := indices[i][0]

View on GitHub (pinned to a1189de023)

Solutions

  1. Check that each component of the parent path is a directory: `ls -la $(dirname <path>)` — remove/rename any regular file with the same name.
  2. Verify write permission on the ancestor directory (chmod/chown or run as the correct user).
  3. Set HOME (or the config-path override) to a writable location.
  4. Free disk space or remount the filesystem read-write if it is read-only.

Example fix

# before: $HOME/.skaffold is a plain file, blocking MkdirAll
$ ls -la ~ | grep .skaffold
-rw-r--r-- 1 user user 0 .skaffold
// after
$ rm ~/.skaffold && mkdir -p ~/.skaffold
Defensive patterns

Strategy: validation

Validate before calling

func canBootstrapConfig(path string) error {
    dir := filepath.Dir(path)
    for d := dir; d != "." && d != "/"; d = filepath.Dir(d) {
        fi, err := os.Stat(d)
        if err == nil && !fi.IsDir() {
            return fmt.Errorf("%s exists and is not a directory", d)
        }
    }
    f, err := os.CreateTemp(dir, ".probe")
    if err != nil {
        return fmt.Errorf("%s not writable: %w", dir, err)
    }
    f.Close(); os.Remove(f.Name())
    return nil
}

Try / catch

if err := util.VerifyOrCreateFile(cfgPath); err != nil {
    if strings.Contains(err.Error(), "creating parent directory") {
        os.RemoveAll(filepath.Dir(cfgPath)) // remove stale non-directory component
        return util.VerifyOrCreateFile(cfgPath)
    }
    return err
}

Prevention

When it happens

Trigger: Running Skaffold when the config path (e.g. ~/.skaffold/config) does not exist and os.Stat reports IsNotExist, then os.MkdirAll on the parent fails — parent path component is a regular file, HOME is not writable, or the target filesystem is read-only.

Common situations: A stale file named `.skaffold` (instead of a directory) sits in $HOME; running in a container as a non-root user with a read-only or unwritable HOME; HOME pointing to a nonexistent/unwritable path in CI; disk full.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/cbff7ca7023890b9. Report an issue: GitHub.