hashicorp/packer · error

malformed packer SBOM output from file %q: %s

Error message

malformed packer SBOM output from file %q: %s

What it means

Thrown when the JSON decoder cannot parse the contents of the SBOM temporary file into hcpSbomProvisioner.PackerSBOM. This means the SBOM written by the preceding provisioner step is absent, empty, or not valid JSON matching the expected shape (RawSBOM, Format, Name fields).

Source

Thrown at packer/provisioner.go:398

	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)
	p.SBOMFormat = provisionerOut.Format
	p.SBOMName = provisionerOut.Name

	return nil
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Verify the SBOM-producing step (e.g. the SBOM datasource/provisioner) ran and completed successfully before this point
  2. Inspect the quoted temp file contents if it still exists to see whether it is empty or malformed
  3. Ensure the SBOM-producing plugin and Packer versions are compatible
  4. Free disk space and rerun — truncation from a full disk is a common cause

Example fix

// before
err = json.NewDecoder(packerSbom).Decode(provisionerOut)
if err != nil {
  return fmt.Errorf("malformed packer SBOM output from file %q: %s", tmpFileName, err)
}
// after
err = json.NewDecoder(packerSbom).Decode(provisionerOut)
if err != nil {
  return fmt.Errorf("malformed packer SBOM output from file %q: %w", tmpFileName, err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate your SBOM-producing step output is valid JSON before the build chain
f, err := os.Open(sbomPath)
if err != nil { log.Fatal(err) }
dec := json.NewDecoder(f)
var probe map[string]json.RawMessage
if err := dec.Decode(&probe); err != nil {
    log.Fatalf("SBOM step output not valid JSON: %v", err)
}
for _, k := range []string{"RawSBOM", "Format", "Name"} {
    if _, ok := probe[k]; !ok {
        log.Fatalf("SBOM JSON missing expected key %q", k)
    }
}

Try / catch

if err := p.Provision(ctx, ui, comm, data); err != nil {
    if strings.HasPrefix(err.Error(), "malformed packer SBOM output") {
        // inspect the upstream SBOM provisioner/datasource logs
    }
    return err
}

Prevention

When it happens

Trigger: Provision reads back the SBOM temp file with json.NewDecoder(...).Decode(&PackerSBOM{}) and the decode fails because the file is empty, truncated, or not the expected JSON structure.

Common situations: A chained SBOM provisioner (e.g. the syft/cyclonedx datasource step) silently produced no output; disk-full during write left a truncated file; plugin version mismatch produces a different JSON schema.

Understand the failure class

Related errors


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