hashicorp/packer · error
failed to open %s for hashing: %w
Error message
failed to open %s for hashing: %w
What it means
fileSHA256 computes the SHA-256 of a downloaded artifact by opening it with os.Open. If the file cannot be opened (does not exist, permission denied, path is a directory, etc.), it wraps the OS error with this message including the path. It indicates the local zip to be verified is unreadable, not that its content is wrong.
Source
Thrown at provisioner/hcp-sbom/packer_release_fetch.go:201
if len(fields) < 2 {
continue
}
candidateFileName := strings.TrimPrefix(fields[len(fields)-1], "*")
if candidateFileName == fileName {
hash := strings.ToLower(fields[0])
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}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Check the wrapped OS error in the message (e.g. 'no such file or directory' vs 'permission denied') to identify the root cause.
- Verify TMPDIR points to a writable directory with free space (df -h /tmp); set TMPDIR to a writable location if needed.
- Check whether antivirus/EDR removed the downloaded file and add an exclusion for the temp download path.
- Confirm nothing deletes the temp file before hashing — downloadURLToTempFile removes it on error, and only the caller's keepCandidate flag preserves it.
Example fix
// before: inheriting an unwritable TMPDIR in a container
// os.Open /tmp/packer-dl-*123.zip: permission denied
// after: ensure a writable temp directory before downloading
if err := os.MkdirAll("/work/tmp", 0o755); err != nil {
return err
}
os.Setenv("TMPDIR", "/work/tmp")
zipPath, err := downloadPackerRelease(ctx, goos, goarch) Defensive patterns
Strategy: validation
Validate before calling
func assertReadableFile(path string) error {
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("artifact missing: %w", err)
}
if info.IsDir() {
return fmt.Errorf("%s is a directory, expected file", path)
}
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("artifact unreadable: %w", err)
}
return f.Close()
} Type guard
func isFileReadable(path string) bool {
f, err := os.Open(path)
if err != nil {
return false
}
_ = f.Close()
return true
} Try / catch
actualSHA, err := fileSHA256(candidateZipPath)
if err != nil {
var pathErr *fs.PathError
if errors.As(err, &pathErr) {
return fmt.Errorf("downloaded artifact %s unavailable (%v); TMPDIR=%s, free disk and AV exclusions should be checked",
candidateZipPath, pathErr.Err, os.TempDir())
}
return err
} Prevention
- Ensure TMPDIR is writable, local, and has enough free space for the ~200MB zip.
- Add antivirus exclusions for your temp download directory on CI runners.
- Run the process with a user that can read/write the temp directory.
- Avoid running under sandboxes that deny /tmp access.
When it happens
Trigger: fileSHA256(path) called on the temp file produced by downloadURLToTempFile; os.Open fails with *fs.PathError — e.g. the temp file was deleted between download and hashing (cleanup defer raced), /tmp is not readable, disk full causing unlink, or a caller passes an empty/invalid path.
Common situations: Read-only or full /tmp (TMPDIR misconfigured); security software (EDR/antivirus) quarantining the downloaded binary; running with restricted permissions or a sandbox that blocks temp-file access; another process cleaning /tmp concurrently.
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
- hash %q: %w
- failed hashing %s: %w
- failed to create output file %q: %s
- failed to write SBOM to destination %q: %s
- read verifier %q: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/f180a0f9222e0672.
Report an issue: GitHub.