kubernetes/kops · error

error creating directories %q: %v

Error message

error creating directories %q: %v

What it means

kOps's asset store extracts downloaded archives into a directory, but to make the extraction atomic it first extracts into a temporary '.tmp-<timestamp>' directory created with os.MkdirAll. When MkdirAll cannot create that directory (permissions, disk full, path issues), addArchive returns 'error creating directories %q: %v' wrapping the underlying OS error with the parent path of the temp dir.

Source

Thrown at upup/pkg/fi/assetstore.go:307

		err = a.addArchive(source, localFile)
		if err != nil {
			return err
		}
	}

	return nil
}

func (a *AssetStore) addArchive(archiveSource *Source, archiveFile string) error {
	extracted := path.Join(a.cacheDir, "extracted/"+path.Base(archiveFile))

	if _, err := os.Stat(extracted); os.IsNotExist(err) {
		// We extract to a temporary dir which we then rename so this is atomic
		// (untarring can be slow, and we might crash / be interrupted half-way through)
		extractedTemp := extracted + ".tmp-" + strconv.FormatInt(time.Now().UnixNano(), 10)
		err := os.MkdirAll(extractedTemp, 0o755)
		if err != nil {
			return fmt.Errorf("error creating directories %q: %v", path.Dir(extractedTemp), err)
		}

		args := []string{"tar", "zxf", archiveFile, "-C", extractedTemp}
		klog.Infof("running extract command %s", args)
		cmd := exec.Command(args[0], args[1:]...)
		output, err := cmd.CombinedOutput()
		if err != nil {
			return fmt.Errorf("error expanding asset file %q %v: %s", archiveFile, err, string(output))
		}

		if err := os.Rename(extractedTemp, extracted); err != nil {
			return fmt.Errorf("error renaming extracted temp dir %s -> %s: %v", extractedTemp, extracted, err)
		}
	}

	localBase := extracted
	assetBase := ""

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped %v OS error to identify the failing path and errno (EACCES/ENOSPC/ENOTDIR).
  2. Fix filesystem permissions or free disk space on the volume holding the asset store working directory.
  3. Remove stale files/dirs at the extraction path so MkdirAll can create parents.
  4. Re-run the command as a user with write access to the working directory.
  5. Retry after clearing any transient condition; the temp dir is unique per nanotimestamp so retries won't collide.

Example fix

// diagnose the wrapped cause instead of only the wrapper
if _, err := os.Stat(extracted); os.IsNotExist(err) {
  extractedTemp := extracted + ".tmp-" + strconv.FormatInt(time.Now().UnixNano(), 10)
  if err := os.MkdirAll(extractedTemp, 0o755); err != nil {
    klog.Warningf("MkdirAll failed for %s: %v", extractedTemp, err)
    return fmt.Errorf("error creating directories %q: %v", path.Dir(extractedTemp), err)
  }
}
Defensive patterns

Strategy: validation

Validate before calling

const extracted = "/var/cache/kops/assets/nodeup"
const extractedTemp = extracted + ".tmp-" + Date.now()
import fs from "fs"
// pre-check writability of the parent dir
fs.accessSync(require("path").dirname(extractedTemp), fs.constants.W_OK)
if (fs.existsSync(extracted)) throw new Error("already extracted: " + extracted)

Type guard

function isNil<T>(v: T | null | undefined): v is null | undefined { return v === null || v === undefined }

Try / catch

try {
  await addURLs(urls)
} catch (e) {
  if (/error creating directories/.test(e.message)) {
    // inspect wrapped cause, fix perms/space, retry once
    console.error("asset dir unwritable:", e.message)
  }
  throw e
}

Prevention

When it happens

Trigger: addURLs -> addArchive where the extracted asset directory does not exist yet and os.MkdirAll on '<extracted>.tmp-<nanotimestamp>' fails — e.g. read-only parent, EACCES, ENOSPC, or a path component is a file.

Common situations: Running kOps as non-root against asset dirs owned by root; disk quota/full on the state store working volume; SELinux/AppArmor blocking writes in the working directory; a stale file occupying a path component of the extraction dir.

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/19347bc813efa138. Report an issue: GitHub.