hashicorp/packer · error

failed to close temp file: %w

Error message

failed to close temp file: %w

What it means

downloadURLToTempFile buffers the downloaded Packer release zip into an os.CreateTemp file and closes it after io.Copy. This error wraps any *os.PathError returned by f.Close(), meaning the final flush/sync of buffered data to disk (or the file-descriptor release) failed. Because the close already failed, the temp file is deleted and the caller must retry; a partial or corrupt file is never returned.

Source

Thrown at provisioner/hcp-sbom/packer_release_fetch.go:138

		return "", fmt.Errorf("HTTP request failed: %w", err)
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode != http.StatusOK {
		_ = f.Close()
		_ = os.Remove(tmpPath)
		return "", fmt.Errorf("HTTP %d for %s", resp.StatusCode, url)
	}

	_, copyErr := io.Copy(f, resp.Body)
	closeErr := f.Close()
	if copyErr != nil {
		_ = os.Remove(tmpPath)
		return "", fmt.Errorf("failed to write download: %w", copyErr)
	}
	if closeErr != nil {
		_ = os.Remove(tmpPath)
		return "", fmt.Errorf("failed to close temp file: %w", closeErr)
	}

	return tmpPath, nil
}

// downloadChecksumFile fetches the SHA256SUMS text file at url.
func downloadChecksumFile(ctx context.Context, client *http.Client, url string) (string, error) {
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return "", fmt.Errorf("failed to build request for %s: %w", url, err)
	}

	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("failed to download %s: %w", url, err)
	}
	defer func() { _ = resp.Body.Close() }()

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Check free space on the filesystem backing os.TempDir() (df -h /tmp) and free space or point TMPDIR to a volume with room for the Packer zip
  2. Set the TMPDIR environment variable to a larger volume and rerun the hcp-sbom provisioning step
  3. Check dmesg / container runtime logs for I/O errors or ephemeral-storage limits and fix the underlying disk or raise the quota
  4. Retry the operation — the code already removed the bad temp file, and downloadPackerRelease wraps this in a retry.Config with 3 tries

Example fix

// before: trusting tmpfs default
// (download fails with "failed to close temp file: ... no space left on device")
// after: point temp files at a larger volume before running packer
// $ export TMPDIR=/var/tmp   # volume with adequate free space
// TMPDIR=/var/tmp packer build template.pkr.hcl
Defensive patterns

Strategy: validation

Validate before calling

// before triggering the download flow, ensure the temp volume has room for the zip
const minFreeBytes = 200 << 20 // Packer zip is ~25-150MB; keep headroom
var st syscall.Statfs_t
if err := syscall.Statfs(os.TempDir(), &st); err != nil {
    return fmt.Errorf("cannot stat temp dir %s: %w", os.TempDir(), err)
}
free := uint64(st.Bavail) * uint64(st.Bsize)
if free < minFreeBytes {
    return fmt.Errorf("only %d bytes free in %s; set TMPDIR to a larger volume", free, os.TempDir())
}

Type guard

// ensure the wrapped cause is a filesystem (PathError) problem you can act on
func asPathError(err error) (*fs.PathError, bool) {
    var pe *fs.PathError
    if errors.As(err, &pe) {
        return pe, true
    }
    return nil, false
}
// usage: if pe, ok := asPathError(err); ok && errors.Is(pe.Err, syscall.ENOSPC) { ... }

Prevention

When it happens

Trigger: f.Close() returns a non-nil error after a successful io.Copy from the HTTP response body — typically ENOSPC (disk full), EIO (disk/device error), or an fsync-level failure while flushing written bytes in downloadURLToTempFile (packer_release_fetch.go:131-138).

Common situations: The disk or tmpfs backing os.TempDir() (e.g. /tmp) is full or nearly full after streaming a large zip; the container/pod ephemeral storage quota is exhausted; underlying storage encountered I/O errors; or a filesystem was unmounted/remounted mid-download.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/ad95c040380bed42. Report an issue: GitHub.