{"record":{"id":"d2de7274dcd1e358","repo":"hashicorp/packer","slug":"failed-hashing-s-w","errorCode":null,"errorMessage":"failed hashing %s: %w","messagePattern":"failed hashing (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/packer_release_fetch.go","lineNumber":207,"sourceCode":"\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}\n\n\tvar zipPath string\n\terr := retry.Config{\n\t\tTries:      3,\n\t\tRetryDelay: func() time.Duration { return 5 * time.Second },\n\t}.Run(ctx, func(ctx context.Context) error {","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/packer_release_fetch.go#L189-L225","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: large temp zip on a flaky network volume\n// failed hashing /tmp/packer-dl-*123.zip: read /tmp/...: input/output error\n\n// after: pin TMPDIR to healthy local disk before invoking the flow\nos.Setenv(\"TMPDIR\", \"/var/tmp\")\nzipPath, err := downloadPackerRelease(ctx, goos, goarch)","handlingStrategy":"retry","validationCode":"func assertStableFile(path string) error {\n    fi1, err := os.Stat(path)\n    if err != nil {\n        return err\n    }\n    time.Sleep(500 * time.Millisecond)\n    fi2, err := os.Stat(path)\n    if err != nil {\n        return fmt.Errorf(\"file %s disappeared during processing: %w\", path, err)\n    }\n    if fi1.Size() != fi2.Size() {\n        return fmt.Errorf(\"file %s is being modified concurrently\", path)\n    }\n    return nil\n}","typeGuard":"null","tryCatchPattern":"actualSHA, err := fileSHA256(candidateZipPath)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed hashing\") {\n        // transient I/O: redownload and rehash via the retry loop\n        return candidateZipPath, downloadPackerRelease(ctx, goos, goarch)\n    }\n    return \"\", err\n}","preventionTips":["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."],"tags":["filesystem","io","sha256","go"],"backgroundTag":"file-read-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"}