hashicorp/packer · error

Unable to create dir for archive %s: %s

Error message

Unable to create dir for archive %s: %s

What it means

PostProcess creates the parent directory of the archive target via os.MkdirAll with mode 0755 before creating the file. This error means the OS refused to create that directory tree (permission denied, path component is a file, read-only filesystem, etc.).

Source

Thrown at post-processor/compress/post-processor.go:144

		generatedData = make(map[interface{}]interface{})
	}

	// These are extra variables that will be made available for interpolation.
	generatedData["BuildName"] = p.config.PackerBuildName
	generatedData["BuilderType"] = p.config.PackerBuilderType
	p.config.ctx.Data = generatedData

	target, err := interpolate.Render(p.config.OutputPath, &p.config.ctx)
	if err != nil {
		return nil, false, false, fmt.Errorf("Error interpolating output value: %s", err)
	} else {
		fmt.Println(target)
	}

	newArtifact := &Artifact{Path: target}

	if err = os.MkdirAll(filepath.Dir(target), os.FileMode(0755)); err != nil {
		return nil, false, false, fmt.Errorf(
			"Unable to create dir for archive %s: %s", target, err)
	}
	outputFile, err := os.Create(target)
	if err != nil {
		return nil, false, false, fmt.Errorf(
			"Unable to create archive %s: %s", target, err)
	}
	defer outputFile.Close()

	// Setup output interface. If we're using compression, output is a
	// compression writer. Otherwise it's just a file.
	var output io.WriteCloser
	errTmpl := "error creating %s writer: %s"
	switch p.config.Algorithm {
	case "bgzf":
		ui.Say(fmt.Sprintf("Using bgzf compression with %d cores for %s",
			runtime.GOMAXPROCS(-1), target))
		output, err = makeBGZFWriter(outputFile, p.config.CompressionLevel)

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Pre-create the target directory with correct ownership/permissions (mkdir -p)
  2. Ensure no existing file occupies a path segment of the target directory
  3. Run packer with a user that has write access to the output location
  4. Point output_path at a writable volume

Example fix

// before (unwritable)
output = "/root/output/artifact.tar.gz"
// after
output = "./output/artifact.tar.gz"
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(renderedTarget)
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := os.MkdirAll(dir, 0755); err != nil {
    return fmt.Errorf("cannot create %s: %w", dir, err)
}

Try / catch

if err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
        // fall back to a writable temp/output directory
    }
}

Prevention

When it happens

Trigger: os.MkdirAll(filepath.Dir(target), 0755) fails during PostProcess — e.g. output_path's directory cannot be created because a parent lacks write permission or a component exists as a regular file.

Common situations: output_path pointing under a root-owned directory; running packer as a non-privileged user; an existing file where a directory is expected (e.g. 'out' is a file); read-only container volume or mounted output 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 hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/f27b62fc5dd31f23. Report an issue: GitHub.