hashicorp/packer · error

failed to create temp file: %w

Error message

failed to create temp file: %w

What it means

downloadURLToTempFile starts by creating a uniquely named temporary file via os.CreateTemp("", "packer-dl-*"+suffix) to hold the downloaded artifact. If the OS cannot create that file, the function aborts immediately with this wrapped error before any network I/O happens. Because the temp file was never created, there is nothing to clean up and the wrapped os error is the underlying cause (e.g. no space, read-only dir, or TMPDIR problems).

Source

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

		semverList = append(semverList, v)
	}

	if len(semverList) == 0 {
		return "", fmt.Errorf("no stable Packer releases found in index at %s", indexURL)
	}

	sort.Sort(semver.Collection(semverList))
	latest := semverList[len(semverList)-1]
	log.Printf("[INFO] Latest stable Packer version from releases index: %s", latest.Original())
	return latest.Original(), nil
}

// downloadURLToTempFile downloads url into a new temp file and returns its path.
// On any error the temp file is removed. The caller owns the returned file on success.
func downloadURLToTempFile(ctx context.Context, client *http.Client, url, suffix string) (string, error) {
	f, err := os.CreateTemp("", "packer-dl-*"+suffix)
	if err != nil {
		return "", fmt.Errorf("failed to create temp file: %w", err)
	}
	tmpPath := f.Name()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		_ = f.Close()
		_ = os.Remove(tmpPath)
		return "", err
	}

	resp, err := client.Do(req)
	if err != nil {
		_ = f.Close()
		_ = os.Remove(tmpPath)
		return "", fmt.Errorf("HTTP request failed: %w", err)
	}
	defer func() { _ = resp.Body.Close() }()

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Check free disk space on the filesystem backing the temp directory (df -h $TMPDIR) and free space if full.
  2. Verify the temp directory exists and is writable by the Packer process: ls -ld ${TMPDIR:-/tmp} and test with touch.
  3. If TMPDIR/TMP/TEMP is set to a bad path, unset it or point it at an existing writable directory.
  4. Run the process with enough OS permissions (or outside the sandbox) so it may create files in the temp dir, or set TMPDIR to a directory it can write.
  5. Inspect the wrapped error in the message (e.g. 'permission denied', 'no space left on device') and fix the matching OS condition.

Example fix

// before: default temp dir may be unusable in the container
path, err := downloadURLToTempFile(ctx, client, url, ".zip")
// after: point the process at a known-writable workspace dir first
os.Setenv("TMPDIR", "/workspace/.tmp") // must exist and be writable
if err := os.MkdirAll("/workspace/.tmp", 0o755); err != nil { return err }
path, err := downloadURLToTempFile(ctx, client, url, ".zip")
Defensive patterns

Strategy: validation

Validate before calling

// Verify the temp directory is writable before invoking the download
func ensureTempWritable() error {
    dir := os.TempDir()
    if info, err := os.Stat(dir); err != nil || !info.IsDir() {
        return fmt.Errorf("temp dir %q missing", dir)
    }
    probe, err := os.CreateTemp(dir, "probe-*")
    if err != nil {
        return fmt.Errorf("temp dir %q not writable: %w", dir, err)
    }
    name := probe.Name()
    probe.Close()
    os.Remove(name)
    return nil
}

Try / catch

path, err := downloadURLToTempFile(ctx, client, url, ".zip")
if err != nil {
    if errors.Is(err, os.ErrPermission) || strings.Contains(err.Error(), "no space left on device") {
        // fix environment: free space or set TMPDIR to a writable dir, then retry once
        os.Setenv("TMPDIR", "/var/tmp")
        path, err = downloadURLToTempFile(ctx, client, url, ".zip")
    }
    if err != nil {
        return fmt.Errorf("cannot stage download: %w", err)
    }
}

Prevention

When it happens

Trigger: os.CreateTemp fails because the temp directory (TMPDIR/TMP/TEMP or /tmp) does not exist or is not writable, the filesystem holding it is full, the process lacks write permission, resource limits (quota, inodes, fd) are exhausted, or a security policy (sandbox/seccomp) blocks temp-file creation.

Common situations: CI runners with a tiny or read-only /tmp; containers where TMPDIR points at a deleted or non-existent volume; disk-full during large builds; hardened containers running as non-root with restricted temp dirs.

Related errors


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