hashicorp/packer · error · ValidationError
invalid bomFormat: %q, expected CycloneDX
Error message
invalid bomFormat: %q, expected CycloneDX
What it means
After successfully decoding as JSON, validateCycloneDX checks that bom.BOMFormat equals 'CycloneDX' (case-insensitive). This ValidationError is thrown when the document parses as JSON but its bomFormat field is absent or some other value, meaning it is not a CycloneDX document (or not identifiable as one).
Source
Thrown at provisioner/hcp-sbom/validate.go:39
func (e *ValidationError) Error() string {
return e.Err.Error()
}
func (e *ValidationError) Unwrap() error {
return e.Err
}
// ValidateCycloneDX is a validation for CycloneDX in JSON format.
func validateCycloneDX(content []byte) error {
decoder := cyclonedx.NewBOMDecoder(bytes.NewBuffer(content), cyclonedx.BOMFileFormatJSON)
bom := new(cyclonedx.BOM)
if err := decoder.Decode(bom); err != nil {
return fmt.Errorf("error parsing CycloneDX SBOM: %w", err)
}
if !strings.EqualFold(bom.BOMFormat, "CycloneDX") {
return &ValidationError{
Err: fmt.Errorf("invalid bomFormat: %q, expected CycloneDX", bom.BOMFormat),
}
}
if bom.SpecVersion.String() == "" {
return &ValidationError{
Err: fmt.Errorf("specVersion is required"),
}
}
return nil
}
// validateSPDX is a validation for SPDX in JSON format.
func validateSPDX(content []byte) error {
doc, err := spdxjson.Read(bytes.NewBuffer(content))
if err != nil {
return fmt.Errorf("error parsing SPDX JSON file: %w", err)
}
View on GitHub (pinned to eb36e3c3e4)
Solutions
- Open the SBOM and check the top-level "bomFormat" field; it must be exactly "CycloneDX" (case-insensitive).
- Re-generate the SBOM with -o cyclonedx-json (syft/trivy) instead of a generic or SPDX output.
- If the file is actually SPDX, fix the SPDX document so validateSPDX succeeds (validateSBOM tries SPDX first).
- Validate with an official CycloneDX validator (cyclonedx-cli validate) to catch schema issues.
- Avoid hand-editing the bomFormat field of generated SBOMs.
Example fix
// before (sbom.json)
{ "specVersion": "1.5", "components": [] }
// after
{ "bomFormat": "CycloneDX", "specVersion": "1.5", "components": [] } Defensive patterns
Strategy: validation
Validate before calling
var probe struct {
BOMFormat string `json:"bomFormat"`
}
if err := json.Unmarshal(content, &probe); err != nil || !strings.EqualFold(probe.BOMFormat, "CycloneDX") {
return fmt.Errorf("not a CycloneDX document: bomFormat=%q", probe.BOMFormat)
} Type guard
func hasCycloneDXFormat(b any) bool {
m, ok := b.(map[string]any)
if !ok { return false }
f, _ := m["bomFormat"].(string)
return strings.EqualFold(f, "CycloneDX")
} Try / catch
var vErr *hcp_sbom.ValidationError
if err := processSBOM(); err != nil {
if errors.As(err, &vErr) && strings.Contains(vErr.Error(), "invalid bomFormat") {
// inspect the file's bomFormat field, regenerate as cyclonedx-json
}
} Prevention
- Keep "bomFormat": "CycloneDX" intact in generated SBOMs.
- Distinguish SPDX vs CycloneDX files by extension/content before provisioning.
- Validate SBOMs with an official validator in CI.
- Pin your SBOM generator version so output shape is stable.
When it happens
Trigger: Content decodes without error but bom.BOMFormat is "" or something like "SPDX"/"syft" — e.g. an SPDX JSON document, a generic JSON file, or CycloneDX output with a missing/wrong bomFormat field, and validateSBOM fell through to the CycloneDX probe after SPDX parsing also failed.
Common situations: Pointing the provisioner at an SPDX JSON file whose parser also errored (so the CycloneDX check reports the format problem); hand-edited SBOM where bomFormat was removed or renamed; tools emitting only specVersion without bomFormat.
Related errors
- specVersion is required
- missing SPDXVersion
- unsupported format: %s
- unsupported scope: %s (supported: squashed, all-layers)
- unsupported scope: %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/830bf650f3718525.
Report an issue: GitHub.