hashicorp/packer · error
unable to compute %s hash for %s
Error message
unable to compute %s hash for %s
What it means
The checksum post-processor failed while copying the artifact file into the hash writer (io.Copy to hash.Hash). It wraps any read/compute failure into a single message naming the checksum type and the artifact path, so the original OS error is lost and must be inferred.
Source
Thrown at post-processor/checksum/post-processor.go:151
newartifact.files = append(newartifact.files, checksumFile)
}
if err := os.MkdirAll(filepath.Dir(checksumFile), os.FileMode(0755)); err != nil {
return nil, false, true, fmt.Errorf("unable to create dir: %s", err.Error())
}
fw, err := os.OpenFile(checksumFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0644))
if err != nil {
return nil, false, true, fmt.Errorf("unable to create file %s: %s", checksumFile, err.Error())
}
fr, err := os.Open(art)
if err != nil {
fw.Close()
return nil, false, true, fmt.Errorf("unable to open file %s: %s", art, err.Error())
}
if _, err = io.Copy(h, fr); err != nil {
fr.Close()
fw.Close()
return nil, false, true, fmt.Errorf("unable to compute %s hash for %s", ct, art)
}
fr.Close()
_, _ = fw.WriteString(fmt.Sprintf("%x\t%s\n", h.Sum(nil), filepath.Base(art)))
fw.Close()
h.Reset()
}
}
// sets keep and forceOverride to true because we don't want to accidentally
// delete the very artifact we're checksumming.
return newartifact, true, true, nil
}
View on GitHub (pinned to eb36e3c3e4)
Solutions
- Re-run packer to rule out a transient I/O error
- Verify the artifact file exists, is readable, and is not being mutated concurrently (chmod/ls -l, check no parallel post-processor deletes it)
- Check disk health/space (dmesg, df) on the output filesystem
- If on a network filesystem, copy the artifact locally before the checksum post-processor
Example fix
// before: original io error is swallowed
return nil, false, true, fmt.Errorf("unable to compute %s hash for %s", ct, art)
// after: preserve cause for diagnosis
return nil, false, true, fmt.Errorf("unable to compute %s hash for %s: %w", ct, art, err) Defensive patterns
Strategy: try-catch
Validate before calling
stat, err := os.Stat(artifactPath)
if err != nil || !stat.Mode().IsRegular() {
return fmt.Errorf("artifact not readable: %w", err)
}
// also ensure free disk space and no concurrent writers to the file Try / catch
if err != nil {
var pe *os.PathError
if errors.As(err, &pe) {
// inspect pe.Op/pe.Path to diagnose read failure
}
// retry once on transient I/O errors before failing the build
} Prevention
- Verify artifact file exists and is a regular file before checksum runs
- Avoid post-processor chains that delete or rewrite the artifact concurrently
- Monitor disk health and free space on the output filesystem
- Run checksums on local storage rather than flaky network mounts
When it happens
Trigger: io.Copy(h, fr) returns an error while hashing the artifact file in PostProcess — typically an I/O read failure (disk error, file truncated/removed between open and read, permissions changed mid-read) or a hash writer write panic-path failure.
Common situations: Running on a full or failing disk; artifact file deleted or shrunk by a later post-processor before checksum runs; network/shared filesystem (NFS/SMB) drop while reading a remotely stored artifact; SELinux/AppArmor denying reads.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- unable to create dir: %s
- unable to create file %s: %s
- unable to open file %s: %s
- failed to open %s: %s
- failed to read %s: %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/354e7684d77c9ecd.
Report an issue: GitHub.