{"record":{"id":"a6c700d14c1a44db","repo":"hashicorp/packer","slug":"error-parsing-cyclonedx-sbom-w","errorCode":null,"errorMessage":"error parsing CycloneDX SBOM: %w","messagePattern":"error parsing CycloneDX SBOM: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/validate.go","lineNumber":34,"sourceCode":"// ValidationError represents an error encountered while validating an SBOM.\ntype ValidationError struct {\n\tErr error\n}\n\nfunc (e *ValidationError) Error() string {\n\treturn e.Err.Error()\n}\n\nfunc (e *ValidationError) Unwrap() error {\n\treturn e.Err\n}\n\n// ValidateCycloneDX is a validation for CycloneDX in JSON format.\nfunc validateCycloneDX(content []byte) error {\n\tdecoder := cyclonedx.NewBOMDecoder(bytes.NewBuffer(content), cyclonedx.BOMFileFormatJSON)\n\tbom := new(cyclonedx.BOM)\n\tif err := decoder.Decode(bom); err != nil {\n\t\treturn fmt.Errorf(\"error parsing CycloneDX SBOM: %w\", err)\n\t}\n\n\tif !strings.EqualFold(bom.BOMFormat, \"CycloneDX\") {\n\t\treturn &ValidationError{\n\t\t\tErr: fmt.Errorf(\"invalid bomFormat: %q, expected CycloneDX\", bom.BOMFormat),\n\t\t}\n\t}\n\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 {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/validate.go#L16-L52","documentation":"validateCycloneDX decodes the SBOM content as CycloneDX JSON using cyclonedx-go's BOMDecoder. This error wraps any decoding error — the input is not valid JSON, or is not shaped like a CycloneDX 1.x document. In validateSBOM it is expected during probing: SPDX is tried first, and a CycloneDX parse failure on non-CycloneDX content leads to the generic 'invalid SBOM format' error.","triggerScenarios":"validateSBOM probes the content as CycloneDX after the SPDX parse failed, and cyclonedx.NewBOMDecoder(...).Decode(bom) errors on malformed JSON or JSON missing required CycloneDX structure (no bomFormat/specVersion fields compatible with the decoder).","commonSituations":"The SBOM source returned HTML/XML/empty output instead of CycloneDX JSON; user pointed the provisioner at a CycloneDX XML file; an older tool generated a non-conformant CycloneDX JSON; a truncated download.","solutions":["Validate the SBOM is syntactically valid JSON: jq . sbom.json.","Confirm the document is CycloneDX JSON (has \"bomFormat\": \"CycloneDX\"), not XML or another format.","Re-generate the SBOM with a current tool (syft, cyclonedx-gomod, trivy) in CycloneDX JSON output.","If the file is SPDX, fix whatever broke SPDX parsing instead — validateSBOM tries SPDX first.","Check the file is not empty or truncated (e.g. incomplete download or failed generation step)."],"exampleFix":"// before: XML CycloneDX fed to JSON-only validator\n$ syft packages -o cyclonedx-xml . > sbom.xml\n// after\n$ syft packages -o cyclonedx-json . > sbom.json","handlingStrategy":"validation","validationCode":"func looksLikeCycloneDXJSON(content []byte) bool {\n\tvar probe struct {\n\t\tBOMFormat   string `json:\"bomFormat\"`\n\t\tSpecVersion string `json:\"specVersion\"`\n\t}\n\tif json.Unmarshal(content, &probe) != nil {\n\t\treturn false\n\t}\n\treturn strings.EqualFold(probe.BOMFormat, \"CycloneDX\") && probe.SpecVersion != \"\"\n}\n// call before handing content to the provisioner","typeGuard":"func isCycloneDX(b any) bool {\n\tm, ok := b.(map[string]any)\n\tif !ok { return false }\n\tf, _ := m[\"bomFormat\"].(string)\n\treturn strings.EqualFold(f, \"CycloneDX\")\n}","tryCatchPattern":"var vErr *hcp_sbom.ValidationError\nif err := run(); err != nil {\n\tif strings.Contains(err.Error(), \"error parsing CycloneDX SBOM\") {\n\t\t// regenerate SBOM as cyclonedx-json before retrying\n\t}\n\tif errors.As(err, &vErr) { /* structured validation failure, show vErr.Err */ }\n}","preventionTips":["Always emit CycloneDX JSON (never XML) from your SBOM generator.","Run cyclonedx-cli validate on generated SBOMs in CI before running Packer.","Check the generator exit status so failed runs don't feed empty/garbage output to the provisioner.","Avoid hand-editing generated SBOM documents."],"tags":["sbom","cyclonedx","json","parsing"],"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"}