{"record":{"id":"27f2cd612a405b85","repo":"hashicorp/packer","slug":"missing-spdxversion","errorCode":null,"errorMessage":"missing SPDXVersion","messagePattern":"missing SPDXVersion","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/validate.go","lineNumber":60,"sourceCode":"\tif bom.SpecVersion.String() == \"\" {\n\t\treturn &ValidationError{\n\t\t\tErr: fmt.Errorf(\"specVersion is required\"),\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// validateSPDX is a validation for SPDX in JSON format.\nfunc validateSPDX(content []byte) error {\n\tdoc, err := spdxjson.Read(bytes.NewBuffer(content))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing SPDX JSON file: %w\", err)\n\t}\n\n\tif doc.SPDXVersion == \"\" {\n\t\treturn &ValidationError{\n\t\t\tErr: fmt.Errorf(\"missing SPDXVersion\"),\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// validateSBOM validates the SBOM file and returns the format of the SBOM.\nfunc validateSBOM(content []byte) (hcpPackerModels.HashicorpCloudPacker20230101SbomFormat, error) {\n\t// Try validating as SPDX\n\tspdxErr := validateSPDX(content)\n\tif spdxErr == nil {\n\t\treturn hcpPackerModels.HashicorpCloudPacker20230101SbomFormatSPDX, nil\n\t}\n\n\tif vErr, ok := spdxErr.(*ValidationError); ok {\n\t\treturn \"\", vErr\n\t}\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/validate.go#L42-L78","documentation":"After a successful SPDX JSON parse, validateSPDX requires doc.SPDXVersion to be non-empty; this ValidationError is thrown when the parsed document lacks an spdxVersion field. An SPDX document without a version cannot be identified as SPDX 2.x, so it is rejected as invalid.","triggerScenarios":"Content parses as JSON but the top-level spdxVersion field is missing or empty (e.g. SPDX 3.0 documents or custom JSON with SPDX-like fields), and validateSBOM's SPDX probe returns this ValidationError, which aborts before the CycloneDX probe.","commonSituations":"SPDX 3.0 output (which uses a different model and no spdxVersion string in the same place) fed to the provisioner; hand-written JSON resembling SPDX but omitting spdxVersion; tooling that strips or renames the field.","solutions":["Ensure the document contains \"spdxVersion\": \"SPDX-2.3\" (or another SPDX-2.x value) at the top level.","Regenerate the SBOM as SPDX 2.x JSON: syft packages -o spdx-json . > sbom.json.","If using SPDX 3.0, convert the document to SPDX 2.3 JSON before use.","Run an SPDX validator (e.g. tools-java Validate) to confirm the document is conformant.","Stop post-processing steps from removing the spdxVersion field."],"exampleFix":"// before\n{ \"documents\": [ ... ] }   // no spdxVersion\n// after\n{ \"spdxVersion\": \"SPDX-2.3\", \"documents\": [ ... ] }","handlingStrategy":"validation","validationCode":"var probe struct {\n\tSPDXVersion string `json:\"spdxVersion\"`\n}\nif err := json.Unmarshal(content, &probe); err != nil {\n\treturn err\n}\nif !strings.HasPrefix(probe.SPDXVersion, \"SPDX-\") {\n\treturn fmt.Errorf(\"spdxVersion missing or invalid: %q\", probe.SPDXVersion)\n}","typeGuard":"func hasSPDXVersion(b any) bool {\n\tm, ok := b.(map[string]any)\n\tif !ok { return false }\n\tv, _ := m[\"spdxVersion\"].(string)\n\treturn v != \"\"\n}","tryCatchPattern":"var vErr *hcp_sbom.ValidationError\nif err := processSBOM(); err != nil {\n\tif errors.As(err, &vErr) && strings.Contains(vErr.Error(), \"missing SPDXVersion\") {\n\t\t// regenerate the SBOM as SPDX 2.x JSON\n\t}\n}","preventionTips":["Ensure \"spdxVersion\": \"SPDX-2.3\" is present in emitted SPDX JSON.","Avoid generators producing SPDX 3.0 documents for this provisioner.","Run an SPDX conformance validator in CI before the Packer build.","Do not post-process SPDX JSON in ways that drop top-level fields."],"tags":["sbom","spdx","validation","schema"],"backgroundTag":"invalid-sbom-format","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}