hashicorp/packer · error

failed to close temporary file for Packer SBOM %s: %s

Error message

failed to close temporary file for Packer SBOM %s: %s

What it means

Thrown during Provision when Packer's internal SBOM temporary file is created successfully but closing the open file handle fails with an OS-level error (e.g. fd exhaustion or an I/O error on Close). The temporary file's name is included so the operator can locate/clean up the leftover file. It wraps the underlying error from tmpFile.Close().

Source

Thrown at packer/provisioner.go:368

func (p *SBOMInternalProvisioner) Provision(
	ctx context.Context, ui packersdk.Ui, comm packersdk.Communicator,
	generatedData map[string]interface{},
) error {
	// Original implementation - all logic now in hcp-sbom provisioner
	cwd, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("failed to get current working directory for Packer SBOM: %s", err)
	}

	tmpFile, err := os.CreateTemp(cwd, "packer-sbom-*.json")
	if err != nil {
		return fmt.Errorf("failed to create internal temporary file for Packer SBOM: %s", err)
	}

	tmpFileName := tmpFile.Name()
	if err = tmpFile.Close(); err != nil {
		return fmt.Errorf("failed to close temporary file for Packer SBOM %s: %s", tmpFileName, err)
	}

	defer func(name string) {
		fileRemoveErr := os.Remove(name)
		if fileRemoveErr != nil {
			log.Printf("Error removing SBOM temporary file %s: %s", name, fileRemoveErr)
		}
	}(tmpFile.Name())

	generatedData["dst"] = tmpFile.Name()

	err = p.Provisioner.Provision(ctx, ui, comm, generatedData)
	if err != nil {
		return err
	}

	packerSbom, err := os.Open(tmpFileName)
	if err != nil {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Raise the open-file limit (ulimit -n) and retry the build, since fd exhaustion is the most common cause
  2. Free disk space / verify the health of the filesystem holding os.Tempdir()
  3. Set PACKER_TMP_DIR (or TMPDIR) to a writable, healthy directory
  4. Check kernel/container logs for I/O errors on the backing storage device

Example fix

// before
if err = tmpFile.Close(); err != nil {
  return fmt.Errorf("failed to close temporary file for Packer SBOM %s: %s", tmpFileName, err)
}
// after
if err = tmpFile.Close(); err != nil {
  return fmt.Errorf("failed to close temporary file for Packer SBOM %s: %w", tmpFileName, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: before running the build, ensure the process can allocate more fds
import "syscall"
n, err := syscall.Getrlimit(syscall.RLIMIT_NOFILE)
if err == nil && n.Cur < 4096 {
    n.Cur = 4096
    syscall.Setrlimit(syscall.RLIMIT_NOFILE, &n)
}

Try / catch

err := provisioner.Run(ctx, ui, comm)
if err != nil {
    var pathErr *os.PathError
    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, syscall.EMFILE) {
        // raise ulimit / retry
    }
    return err
}

Prevention

When it happens

Trigger: Running a build where the HCP SBOM provisioner path in packer.Provision creates a temporary file via os.CreateTemp (in Packer's tmp directory) and the subsequent Close() call returns an error, typically due to file-descriptor exhaustion (EMFILE) or disk I/O failure.

Common situations: Systems with an exhausted ulimit -n (too many open files); disk errors or a full/failed filesystem; containers with limited fds; sandboxed environments blocking file operations in the temp directory.

Related errors


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