#11253·trivy

bug(license): license scanner silently drops licenses that fail SPDX parsing

Author: DmitriyLewenCreated Sep 15, 2026Updated Sep 15, 2026
Labelskind/bugscan/license

Description

If a package license name can't be parsed as an SPDX expression (e.g. CDDL + GPLv2 with classpath exception or Apache License (2.0) with Commons Clause), Trivy doesn't report this license as a finding. It is missing from the table, from Results[].Licenses in the JSON report, from SARIF and from the totals, even with --severity UNKNOWN, and nothing is logged about it. Parsable but unclassified names are reported as unknown / UNKNOWN.

Originally reported in #11250.

Reproduction

sbom.cdx.json:

json
{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "version": 1,
  "components": [
    {
      "type": "library",
      "name": "pkg-valid-spdx",
      "version": "1.0.0",
      "purl": "pkg:maven/example/[email protected]",
      "licenses": [{ "license": { "id": "MIT" } }]
    },
    {
      "type": "library",
      "name": "pkg-cddl-gpl",
      "version": "1.0.0",
      "purl": "pkg:maven/example/[email protected]",
      "licenses": [{ "license": { "name": "CDDL + GPLv2 with classpath exception" } }]
    },
    {
      "type": "library",
      "name": "pkg-commons-clause",
      "version": "1.0.0",
      "purl": "pkg:maven/example/[email protected]",
      "licenses": [{ "license": { "name": "Apache License (2.0) with Commons Clause" } }]
    }
  ]
}
bash
$ trivy sbom --scanners license -q sbom.cdx.json

Actual result

Only 1 of 3 licenses is reported:

Java (license)
==============
Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

┌────────────────────────┬─────────┬────────────────┬──────────┐
│        Package         │ License │ Classification │ Severity │
├────────────────────────┼─────────┼────────────────┼──────────┤
│ example:pkg-valid-spdx │ MIT     │ notice         │ LOW      │
└────────────────────────┴─────────┴────────────────┴──────────┘

Expected result

Unparsable names are reported as unknown / UNKNOWN:

Java (license)
==============
Total: 3 (UNKNOWN: 2, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

┌────────────────────────────┬──────────────────────────────────────────┬────────────────┬──────────┐
│          Package           │                 License                  │ Classification │ Severity │
├────────────────────────────┼──────────────────────────────────────────┼────────────────┼──────────┤
│ example:pkg-cddl-gpl       │ CDDL + GPLv2 with classpath exception    │ unknown        │ UNKNOWN  │
├────────────────────────────┼──────────────────────────────────────────┤                │          │
│ example:pkg-commons-clause │ Apache License (2.0) with Commons Clause │                │          │
├────────────────────────────┼──────────────────────────────────────────┼────────────────┼──────────┤
│ example:pkg-valid-spdx     │ MIT                                      │ notice         │ LOW      │
└────────────────────────────┴──────────────────────────────────────────┴────────────────┴──────────┘

Root cause

If expression.Normalize returns an error, Scanner.Scan returns the unknown category with an empty severity. filterLicenses only keeps licenses whose severity is in --severity, and an empty string is never in that list.

In client/server mode these licenses are still shown as UNKNOWN, because the RPC conversion turns the empty severity into UNKNOWN.

Proposed fix

  1. Return the UNKNOWN severity for unparsable names, as is already done for unclassified names and for license texts in ScanTextLicense.
  2. Skip licenses with an empty name when scanning package licenses. Such licenses appear, for example, for SPDX packages without the optional licenseDeclared field (strings.Split("", ",") returns [""]). They are currently hidden by the same bug, and after step 1 they would become UNKNOWN findings without a name that can't be evaluated.