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
- Pre-create the target directory with correct ownership/permissions (mkdir -p)
- Ensure no existing file occupies a path segment of the target directory
- Run packer with a user that has write access to the output location
- 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
- Pre-create output directories with correct ownership
- Ensure no file occupies a directory-name path segment
- Run packer as a user with write access to the output location
- Avoid read-only mounts for output paths
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
- unable to create dir: %s
- unable to create file %s: %s
- Unable to create archive %s: %s
- could not create plugin folder %q: %w
- could not create final plugin binary file: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/f27b62fc5dd31f23.
Report an issue: GitHub.