hashicorp/packer · error
failed hashing %s: %w
Error message
failed hashing %s: %w
What it means
fileSHA256 streams the opened file into a sha256.Hash via io.Copy. If the read/copy fails mid-stream (I/O error while reading the file, hardware/disk error, file truncated by an external process, or the hash writer failing), it wraps the error with this message. The file opened fine, but its contents could not be fully read to compute the digest.
Source
Thrown at provisioner/hcp-sbom/packer_release_fetch.go:207
if !isValidSHA256Hex(hash) {
return "", fmt.Errorf("invalid SHA256 checksum format for %s in SHA256SUMS", fileName)
}
return hash, nil
}
}
return "", fmt.Errorf("checksum for %s not found in SHA256SUMS", fileName)
}
func fileSHA256(path string) (string, error) {
f, err := os.Open(path)
if err != nil {
return "", fmt.Errorf("failed to open %s for hashing: %w", path, err)
}
defer func() { _ = f.Close() }()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return "", fmt.Errorf("failed hashing %s: %w", path, err)
}
return hex.EncodeToString(h.Sum(nil)), nil
}
// downloadPackerRelease fetches the latest stable Packer version from the
// HashiCorp releases index (releases.hashicorp.com/packer/index.json), then
// downloads and checksum-verifies the zip for the given GOOS/GOARCH.
// All HTTP operations are retried up to three times.
func downloadPackerRelease(ctx context.Context, goos, goarch string) (string, error) {
base := getReleaseBaseURL()
client := &http.Client{Timeout: 5 * time.Minute}
var zipPath string
err := retry.Config{
Tries: 3,
RetryDelay: func() time.Duration { return 5 * time.Second },
}.Run(ctx, func(ctx context.Context) error {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Retry the whole download-and-verify flow — downloadPackerRelease's retry.Config (3 tries) already re-runs it; a transient I/O error typically clears on a fresh attempt.
- Check disk health and free space on the volume backing the temp directory (dmesg for I/O errors, df).
- Avoid temp dirs on network/FUSE filesystems; set TMPDIR to local disk.
- Ensure no external cleanup (tmpwatch/systemd-tmpfiles) can delete the file while it is being processed.
Example fix
// before: large temp zip on a flaky network volume
// failed hashing /tmp/packer-dl-*123.zip: read /tmp/...: input/output error
// after: pin TMPDIR to healthy local disk before invoking the flow
os.Setenv("TMPDIR", "/var/tmp")
zipPath, err := downloadPackerRelease(ctx, goos, goarch) Defensive patterns
Strategy: retry
Validate before calling
func assertStableFile(path string) error {
fi1, err := os.Stat(path)
if err != nil {
return err
}
time.Sleep(500 * time.Millisecond)
fi2, err := os.Stat(path)
if err != nil {
return fmt.Errorf("file %s disappeared during processing: %w", path, err)
}
if fi1.Size() != fi2.Size() {
return fmt.Errorf("file %s is being modified concurrently", path)
}
return nil
} Type guard
null
Try / catch
actualSHA, err := fileSHA256(candidateZipPath)
if err != nil {
if strings.Contains(err.Error(), "failed hashing") {
// transient I/O: redownload and rehash via the retry loop
return candidateZipPath, downloadPackerRelease(ctx, goos, goarch)
}
return "", err
} Prevention
- Keep temp artifacts on healthy local disks, not network/FUSE mounts.
- Monitor disk health (SMART/dmesg) on runners that hash large artifacts.
- Disable aggressive tmpwatch/systemd-tmpfiles cleanup of files younger than the build duration.
- Hash immediately after download and before any cleanup defers can remove the file.
When it happens
Trigger: io.Copy(h, f) returns a non-nil error while hashing the downloaded Packer zip — e.g. the temp file was truncated/deleted mid-read, underlying storage returned EIO, an FUSE/network filesystem backed /tmp dropped the file, or the file was modified concurrently by another process.
Common situations: Disk or storage failures on CI runners using network-attached temp volumes; container tmpfs exhaustion forcing errors during read; concurrent /tmp cleanup daemons deleting large temp files; failing disks producing read I/O errors on large downloads.
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
- failed to open %s for hashing: %w
- failed to open %s: %s
- failed to read %s: %s
- read attestation %q: %w
- hash %q: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/d2de7274dcd1e358.
Report an issue: GitHub.