{"record":{"id":"f180a0f9222e0672","repo":"hashicorp/packer","slug":"failed-to-open-s-for-hashing-w","errorCode":null,"errorMessage":"failed to open %s for hashing: %w","messagePattern":"failed to open (.+?) for hashing: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/packer_release_fetch.go","lineNumber":201,"sourceCode":"\t\tif len(fields) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tcandidateFileName := strings.TrimPrefix(fields[len(fields)-1], \"*\")\n\t\tif candidateFileName == fileName {\n\t\t\thash := strings.ToLower(fields[0])\n\t\t\tif !isValidSHA256Hex(hash) {\n\t\t\t\treturn \"\", fmt.Errorf(\"invalid SHA256 checksum format for %s in SHA256SUMS\", fileName)\n\t\t\t}\n\t\t\treturn hash, nil\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"checksum for %s not found in SHA256SUMS\", fileName)\n}\n\nfunc fileSHA256(path string) (string, error) {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to open %s for hashing: %w\", path, err)\n\t}\n\tdefer func() { _ = f.Close() }()\n\n\th := sha256.New()\n\tif _, err := io.Copy(h, f); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed hashing %s: %w\", path, err)\n\t}\n\n\treturn hex.EncodeToString(h.Sum(nil)), nil\n}\n\n// downloadPackerRelease fetches the latest stable Packer version from the\n// HashiCorp releases index (releases.hashicorp.com/packer/index.json), then\n// downloads and checksum-verifies the zip for the given GOOS/GOARCH.\n// All HTTP operations are retried up to three times.\nfunc downloadPackerRelease(ctx context.Context, goos, goarch string) (string, error) {\n\tbase := getReleaseBaseURL()\n\tclient := &http.Client{Timeout: 5 * time.Minute}","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/packer_release_fetch.go#L183-L219","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: inheriting an unwritable TMPDIR in a container\n// os.Open /tmp/packer-dl-*123.zip: permission denied\n\n// after: ensure a writable temp directory before downloading\nif err := os.MkdirAll(\"/work/tmp\", 0o755); err != nil {\n    return err\n}\nos.Setenv(\"TMPDIR\", \"/work/tmp\")\nzipPath, err := downloadPackerRelease(ctx, goos, goarch)","handlingStrategy":"validation","validationCode":"func assertReadableFile(path string) error {\n    info, err := os.Stat(path)\n    if err != nil {\n        return fmt.Errorf(\"artifact missing: %w\", err)\n    }\n    if info.IsDir() {\n        return fmt.Errorf(\"%s is a directory, expected file\", path)\n    }\n    f, err := os.Open(path)\n    if err != nil {\n        return fmt.Errorf(\"artifact unreadable: %w\", err)\n    }\n    return f.Close()\n}","typeGuard":"func isFileReadable(path string) bool {\n    f, err := os.Open(path)\n    if err != nil {\n        return false\n    }\n    _ = f.Close()\n    return true\n}","tryCatchPattern":"actualSHA, err := fileSHA256(candidateZipPath)\nif err != nil {\n    var pathErr *fs.PathError\n    if errors.As(err, &pathErr) {\n        return fmt.Errorf(\"downloaded artifact %s unavailable (%v); TMPDIR=%s, free disk and AV exclusions should be checked\",\n            candidateZipPath, pathErr.Err, os.TempDir())\n    }\n    return err\n}","preventionTips":["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."],"tags":["filesystem","file-io","sha256","go"],"backgroundTag":"file-open-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}