kubernetes/kops · error

error creating directories for destination file %q: %v

Error message

error creating directories for destination file %q: %v

What it means

downloadURLToFile prepares the destination directory with os.MkdirAll before downloading. If creating the parent directories fails, it wraps the OS error with the destination path. This is a filesystem permission/path problem, not a download problem.

Source

Thrown at upup/pkg/fi/http.go:56

// If hash is non-nil, it will also verify that it matches the hash of the downloaded file.
func DownloadURL(ctx context.Context, url string, dest string, hash *hashing.Hash) (*hashing.Hash, error) {
	if hash != nil {
		match, err := fileHasHash(dest, hash)
		if err != nil {
			return nil, err
		}
		if match {
			return hash, nil
		}
	}

	return downloadURLToFile(ctx, url, dest, hash)
}

func downloadURLToFile(ctx context.Context, url string, destPath string, hash *hashing.Hash) (*hashing.Hash, error) {
	dir := filepath.Dir(destPath)
	if err := os.MkdirAll(dir, 0o755); err != nil {
		return nil, fmt.Errorf("error creating directories for destination file %q: %v", destPath, err)
	}

	output, err := os.CreateTemp(dir, "."+filepath.Base(destPath)+".tmp")
	if err != nil {
		return nil, fmt.Errorf("error creating temporary file for download %q: %v", destPath, err)
	}
	tempPath := output.Name()
	defer os.Remove(tempPath)

	actual, err := downloadURLToWriter(ctx, url, output, hash)
	if closeErr := output.Close(); closeErr != nil && err == nil {
		err = closeErr
	}
	if err != nil {
		return nil, err
	}
	if err := os.Chmod(tempPath, 0o644); err != nil {
		return nil, fmt.Errorf("error setting mode on downloaded file %q: %v", tempPath, err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped %v error and verify the parent directory is writable by the current user
  2. Create the directory manually with correct ownership if needed
  3. Remove or rename any non-directory file occupying the path
  4. Run with elevated permissions or choose a writable destination

Example fix

// before
mkdir -p /usr/local/share/kops (permission denied)
// after
sudo mkdir -p /usr/local/share/kops && sudo chown $(whoami) /usr/local/share/kops
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(destPath)
if info, err := os.Stat(dir); err == nil && !info.IsDir() {
    return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
    return err
}

Try / catch

if err := fi.DownloadURL(ctx, url, dest, nil); err != nil {
    var pe *os.PathError
    if errors.As(errors.Unwrap(err), &pe) || errors.As(err, &pe) {
        log.Printf("filesystem error on %s: %v", pe.Path, pe.Err)
    }
    return err
}

Prevention

When it happens

Trigger: os.MkdirAll(filepath.Dir(destPath), 0o755) returns an error: unwritable parent, path component is a file, or read-only filesystem.

Common situations: Asset/ filestore destination under a root-owned directory; a file exists where a directory is expected; running without sufficient privileges; read-only container filesystem.

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 kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/48dfbafaeae33e5d. Report an issue: GitHub.