hashicorp/packer · error
Unable to read file %s: %s
Error message
Unable to read file %s: %s
What it means
createTarArchive could not open one of the artifact files for reading while building the tar stream in Packer's compress post-processor. os.Open(path) failed for a specific path, so tar creation stops and PostProcess wraps the failure as 'Error creating tar'.
Source
Thrown at post-processor/compress/post-processor.go:384
}
func makePgzipWriter(output io.WriteCloser, compressionLevel int) (io.WriteCloser, error) {
gzipWriter, err := pgzip.NewWriterLevel(output, compressionLevel)
if err != nil {
return nil, ErrInvalidCompressionLevel
}
_ = gzipWriter.SetConcurrency(500000, runtime.GOMAXPROCS(-1))
return gzipWriter, nil
}
func createTarArchive(files []string, output io.WriteCloser) error {
archive := tar.NewWriter(output)
defer archive.Close()
for _, path := range files {
file, err := os.Open(path)
if err != nil {
return fmt.Errorf("Unable to read file %s: %s", path, err)
}
defer file.Close()
fi, err := file.Stat()
if err != nil {
return fmt.Errorf("Unable to get fileinfo for %s: %s", path, err)
}
header, err := tar.FileInfoHeader(fi, path)
if err != nil {
return fmt.Errorf("Failed to create tar header for %s: %s", path, err)
}
// workaround for archive format on go >=1.10
setHeaderFormat(header)
if err := archive.WriteHeader(header); err != nil {
return fmt.Errorf("Failed to write tar header for %s: %s", path, err)View on GitHub (pinned to eb36e3c3e4)
Solutions
- Check the failing path from the error: verify it exists and is readable (ls -l)
- Fix permissions or restore the missing file before the compress step
- Reorder post-processors so nothing deletes artifact files before compress runs
- Re-run the build from the builder step to regenerate the artifact files
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: every artifact path must exist and be a readable regular file
for _, p := range artifact.Files() {
fi, err := os.Stat(p)
if err != nil { return fmt.Errorf("cannot tar %s: %w", p, err) }
if !fi.Mode().IsRegular() { return fmt.Errorf("skipping non-regular file %s", p) }
if file, err := os.Open(p); err != nil { return err } else { file.Close() }
} Try / catch
// Go: unwrap to find the failing path
if err != nil && strings.Contains(err.Error(), "Error creating tar") {
if strings.Contains(err.Error(), "Unable to read file") {
// log path from inner message; restore permissions/file and retry
}
return err
} Prevention
- Never delete artifact files between build and post-process stages
- Grant the Packer user read access to all artifact paths
- Validate artifact file lists before the compress step
- Run artifact-mutating post-processors after compression, not before
When it happens
Trigger: createTarArchive iterates artifact.Files() and os.Open returns an error for one path: file deleted after the artifact was produced, permission denied, or the path is a dangling symlink/directory.
Common situations: Artifact files removed between builder completion and the compress post-processor; running Packer without read permission on generated disk images; checksum/sidecar files referenced by the artifact no longer present.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- Unable to get fileinfo for %s: %s
- unable to create dir: %s
- unable to create file %s: %s
- unable to open file %s: %s
- Error creating tar: %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/5faf75d859b1ef0a.
Report an issue: GitHub.