hashicorp/packer · error · ValidationError
specVersion is required
Error message
specVersion is required
What it means
validateCycloneDX requires a non-empty bom.SpecVersion after successful decode; this ValidationError is thrown when the CycloneDX document lacks a specVersion (or it is empty). A CycloneDX SBOM without a spec version cannot be mapped to a concrete schema version, so it is rejected.
Source
Thrown at provisioner/hcp-sbom/validate.go:44
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)
}
if doc.SPDXVersion == "" {
return &ValidationError{
Err: fmt.Errorf("missing SPDXVersion"),
}
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Add a valid "specVersion" (e.g. "1.5", "1.4") to the top-level CycloneDX JSON object.
- Re-generate the SBOM with the upstream tool rather than hand-editing.
- Validate with cyclonedx-cli validate to confirm the document conforms to the declared spec version.
- If generation is scripted, check no jq/transform step removes specVersion.
Example fix
// before
{ "bomFormat": "CycloneDX", "components": [] }
// after
{ "bomFormat": "CycloneDX", "specVersion": "1.5", "components": [] } Defensive patterns
Strategy: validation
Validate before calling
var probe struct {
BOMFormat string `json:"bomFormat"`
SpecVersion string `json:"specVersion"`
}
if err := json.Unmarshal(content, &probe); err != nil {
return err
}
if probe.SpecVersion == "" {
return fmt.Errorf("specVersion missing from CycloneDX SBOM")
} Type guard
func hasSpecVersion(b any) bool {
m, ok := b.(map[string]any)
if !ok { return false }
sv, _ := m["specVersion"].(string)
return sv != ""
} Try / catch
var vErr *hcp_sbom.ValidationError
if err := processSBOM(); err != nil {
if errors.As(err, &vErr) && strings.Contains(vErr.Error(), "specVersion is required") {
// regenerate the SBOM; do not hand-patch specVersion
}
} Prevention
- Never strip top-level fields (specVersion, bomFormat) when post-processing SBOM JSON.
- Pin a CycloneDX spec version (1.4/1.5) in your generator configuration.
- Add a schema-validation CI step (cyclonedx-cli validate) before Packer runs.
- Regenerate rather than hand-edit SBOM documents.
When it happens
Trigger: Content has bomFormat "CycloneDX" and decodes, but the specVersion field is missing or empty in the JSON, so bom.SpecVersion.String() returns ""; reached via validateSBOM when the SPDX probe failed first.
Common situations: Hand-crafted or hand-trimmed CycloneDX JSON that dropped "specVersion"; a broken generator producing partial documents; aggressive post-processing that stripped fields from the SBOM.
Related errors
- invalid bomFormat: %q, expected CycloneDX
- 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/eed1e00fe1810458.
Report an issue: GitHub.