hashicorp/packer · error

failed to open Packer SBOM file %q: %s

Error message

failed to open Packer SBOM file %q: %s

What it means

Provisioning error in the SBOM hook (Provision): after the wrapped provisioner ran, the temporary SBOM output file could not be reopened with os.Open — likely deleted by the provisioner, a full tmpfs, or permission changes on the temp path.

Source

Thrown at packer/provisioner.go:387

	}

	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 {
		return fmt.Errorf("failed to open Packer SBOM file %q: %s", tmpFileName, err)
	}
	defer func() {
		if err := packerSbom.Close(); err != nil {
			log.Printf("[WARN] Failed to close Packer SBOM file: %s", err)
		}
	}()

	provisionerOut := &hcpSbomProvisioner.PackerSBOM{}
	err = json.NewDecoder(packerSbom).Decode(provisionerOut)
	if err != nil {
		return fmt.Errorf("malformed packer SBOM output from file %q: %s", tmpFileName, err)
	}

	encoder, err := zstd.NewWriter(nil, zstd.WithEncoderLevel(zstd.SpeedBestCompression))
	if err != nil {
		return fmt.Errorf("failed to create zstd encoder: %s", err)
	}
	p.CompressedData = encoder.EncodeAll(provisionerOut.RawSBOM, nil)

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Ensure the provisioned script doesn't delete files in its working/temp directory
  2. Check the temp filesystem for space and write permissions

Example fix

// before
packerSbom, err := os.Open(tmpFileName)
if err != nil {
  return fmt.Errorf("failed to open Packer SBOM file %q: %s", tmpFileName, err)
}
// after
packerSbom, err := os.Open(tmpFileName)
if err != nil {
  return fmt.Errorf("failed to open Packer SBOM file %q: %w", tmpFileName, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: check the temp directory is writable and stable before the build
import "os"
tmp := os.TempDir() // or PACKER_TMP_DIR if set
info, err := os.Stat(tmp)
if err != nil || !info.IsDir() {
    log.Fatalf("temp dir %q unusable: %v", tmp, err)
}
probe, err := os.CreateTemp(tmp, "packer-sbom-probe-*")
if err != nil {
    log.Fatalf("cannot create files in %q: %v", tmp, err)
}
probe.Close(); os.Remove(probe.Name())

Try / catch

if err := p.Provision(ctx, ui, comm, data); err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) && errors.Is(pe.Err, os.ErrNotExist) {
        // temp file vanished: check tmp-cleaners, rerun
    }
    return err
}

Prevention

When it happens

Trigger: Provision calls os.Open(tmpFileName) on the freshly created SBOM temp file and receives an error — the file was deleted between creation and open, permissions changed, or the temp dir became inaccessible.

Common situations: Cleanup daemons (e.g. systemd-tmpfiles) removing files from TMPDIR mid-build; PACKER_TMP_DIR/TMPDIR pointing at a read-only or removed volume; permission changes by another process; NFS/overlayfs flakiness in containers.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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