vxcontrol/pentagi · error

failed to create directory '%s': %w

Error message

failed to create directory '%s': %w

What it means

For a tar entry of type TypeDir, ExtractTar runs os.MkdirAll(entryPath, 0755) and wraps any failure in this error. The path has already been cleaned and containment-checked, so failures are environmental: the filesystem refused directory creation at the sanitized path.

Source

Thrown at backend/pkg/flowfiles/files.go:399

		if err == io.EOF {
			break
		}
		if err != nil {
			return fmt.Errorf("failed to read tar entry: %w", err)
		}
		if hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink {
			continue
		}

		entryPath := filepath.Join(destDir, filepath.Clean(filepath.FromSlash(hdr.Name)))
		if !IsWithinDir(entryPath, destDir) {
			continue
		}

		switch hdr.Typeflag {
		case tar.TypeDir:
			if err := os.MkdirAll(entryPath, 0755); err != nil {
				return fmt.Errorf("failed to create directory '%s': %w", entryPath, err)
			}
		case tar.TypeReg, tar.TypeRegA:
			if hdr.Size < 0 {
				return fmt.Errorf("tar entry '%s' has invalid size %d", hdr.Name, hdr.Size)
			}
			filesCount++
			if filesCount > MaxPullFiles {
				return fmt.Errorf("tar archive exceeds maximum file count of %d", MaxPullFiles)
			}
			totalSize += hdr.Size
			if totalSize > MaxPullTotalSize {
				return fmt.Errorf("tar archive exceeds maximum total size of %d bytes", MaxPullTotalSize)
			}

			if err := os.MkdirAll(filepath.Dir(entryPath), 0755); err != nil {
				return fmt.Errorf("failed to create parent directory for '%s': %w", entryPath, err)
			}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Ensure destDir exists and is writable before calling ExtractTar (os.MkdirAll(destDir, 0755)).
  2. Clean stale extraction targets: remove a conflicting non-directory file at the entry path (check the wrapped os error for ENOTDIR/EEXIST).
  3. Fix ownership/permissions of destDir for the service account.
  4. Check disk space on the destination volume.

Example fix

// before
if err := flowfiles.ExtractTar(rc, destDir); err != nil { return err }
// after
if err := os.MkdirAll(destDir, 0o755); err != nil { return err }
if err := flowfiles.ExtractTar(rc, destDir); err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(destDir)
if err != nil {
    if err := os.MkdirAll(destDir, 0o755); err != nil {
        return fmt.Errorf("cannot prepare destDir: %w", err)
    }
} else if !info.IsDir() {
    return fmt.Errorf("%s exists and is not a directory", destDir)
}

Try / catch

err := flowfiles.ExtractTar(rc, destDir)
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.EACCES) || errors.Is(pe.Err, syscall.ENOTDIR)) {
        // stale/conflicting layout: wipe and retry once on a clean dir
        os.RemoveAll(destDir)
        os.MkdirAll(destDir, 0o755)
        return flowfiles.ExtractTar(rc, destDir) // note: rc must be restartable
    }
    return err
}

Prevention

When it happens

Trigger: os.MkdirAll fails while extracting a directory entry from PullFlowFiles' archive: destDir does not exist or is read-only, a file already exists at entryPath (MkdirAll returns ENOTDIR), disk full, or permission denied.

Common situations: Re-extracting an archive over a previous extraction where a stale file occupies a directory path; read-only container volume; running the service as a non-root user lacking write access to destDir.

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 vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/4d5dd56711d9fa1d. Report an issue: GitHub.