hashicorp/packer · error

SBOM validation failed: %s

Error message

SBOM validation failed: %s

What it means

Returned by processSBOMForHCP (provisioner/hcp-sbom/provisioner.go:881) when validateSBOM rejects the downloaded SBOM bytes. Packer requires a recognizable SBOM format (SPDX or CycloneDX JSON) before storing it for HCP upload, so unrecognized, truncated, or non-JSON content aborts processing.

Source

Thrown at provisioner/hcp-sbom/provisioner.go:881

	}

	if err := comm.Start(ctx, cmd); err != nil {
		ui.Error(fmt.Sprintf("Failed to cleanup: %s", err))
		return
	}

	cmd.Wait()
	if cmd.ExitStatus() != 0 {
		ui.Error(fmt.Sprintf("Cleanup command failed for %s with exit status %d", remotePath, cmd.ExitStatus()))
	}
}

// processSBOMForHCP validates, compresses, and prepares SBOM for HCP upload
func (p *Provisioner) processSBOMForHCP(generatedData map[string]interface{}, sbomData []byte) error {
	// Validate SBOM format
	format, err := validateSBOM(sbomData)
	if err != nil {
		return fmt.Errorf("SBOM validation failed: %s", err)
	}

	// Get destination path from generatedData
	pkrDst, ok := generatedData["dst"].(string)
	if !ok || pkrDst == "" {
		return fmt.Errorf("packer destination path missing from configs: this is an internal error")
	}

	// Write PackerSBOM to destination
	outFile, err := os.Create(pkrDst)
	if err != nil {
		return fmt.Errorf("failed to create output file %q: %s", pkrDst, err)
	}
	defer func() {
		_ = outFile.Close() // Cleanup, ignore error
	}()

	err = json.NewEncoder(outFile).Encode(PackerSBOM{

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Read the inner validateSBOM error — it names whether the content was unparseable JSON or an unknown format/BOM.
  2. Set scanner_args to request JSON output explicitly (e.g. spdx-json or cyclonedx-json format for syft-style tools).
  3. Inspect the generated SBOM content (scanner stdout in the log, or the remote file) for stray log lines or truncation.
  4. Update the guest scanner binary version so it emits a supported, current SBOM format.
  5. Ensure execute_command does not prepend commands that print to stdout before the redirect (they corrupt the file).

Example fix

// before: human-readable output fails validation
scanner_args = ["--format", "table"]
// after: valid machine-readable SBOM
scanner_args = ["--format", "spdx-json"]
Defensive patterns

Strategy: validation

Validate before calling

// Validate the SBOM before handing it to the provisioner
var probe map[string]interface{}
if json.Unmarshal(sbomBytes, &probe) != nil { /* not JSON: scanner args are wrong */ }
// require a known SBOM envelope
if _, ok := probe["bomFormat"]; !ok {
    if _, ok := probe["spdxVersion"]; !ok { /* unknown SBOM format */ }
}

Try / catch

if err := p.processSBOMForHCP(generatedData, sbomData); err != nil {
    if strings.Contains(err.Error(), "validation failed") { /* fix scanner format args */ }
    return err
}

Prevention

When it happens

Trigger: Downloaded bytes fail validateSBOM: scanner produced a text/table report instead of JSON, output was truncated mid-write, an HTML error page or log text got redirected into the output file, or the scanner emitted an unsupported SBOM version.

Common situations: scanner_args forcing human-readable format (--format table/text); scanner printing warnings to stdout before the JSON corrupting the document; old scanner version emitting an unsupported format; guest locale/encoding mangling output; mixing this provisioner with an execute_command meant for a different tool.

Related errors


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