Why don't my SBOM and advisory package names match?

Short answer: both files are correct, and they are describing the same package in two different spellings. An exact-match comparison takes each at its word, so the mismatch is real until one spelling is folded onto the other.

Where the mismatches come from

Three places, in roughly the order they bite:

  1. The registry is named differently. A package URL carries a purl type; an OSV advisory carries an ecosystem name. For several registries those are two strings for one place.
  2. Maven punctuates differently. A purl splits the coordinate into namespace and name; OSV writes group:artifact.
  3. OSV adds a distribution qualifier. An ecosystem can arrive as Alpine:v3.19 where the SBOM simply says alpine.

None of these are visible as errors in either file, which is why a hand-rolled comparison tends to report a confident, wrong zero.

The registries that are spelled two ways

Five, and only five, of the registries this tool reads are named differently by the two formats:

OSV ecosystempurl type
crates.iocargo
Gogolang
Packagistcomposer
RubyGemsgem
SwiftURLswift

Everything else in the table this tool reads — npm, PyPI, Maven, NuGet, Hex, Pub, CRAN, Hackage — already agrees between the two, once case is set aside. Where the two disagree, the purl spelling wins, because purl is the identifier the SBOM formats themselves carry.

Questions

Why doesn't my SBOM's package name match the advisory's?

Because the two files use different naming conventions for the same registry, and an exact-match comparison takes them at their word. A CycloneDX or SPDX SBOM carries package URLs, whose type is the registry's purl spelling. An OSV advisory carries an ecosystem name instead, and for several registries that is a different string for the same place: golang against Go, cargo against crates.io, packagist against composer, rubygems against gem. Nothing is wrong with either file. They simply never meet until one spelling is folded onto the other.

Why do Maven packages fail when every other ecosystem works?

Maven is the one ecosystem where the two conventions disagree about punctuation rather than about a registry's name. A package URL splits a Maven coordinate into a namespace and a name, while OSV writes the same coordinate as group colon artifact. Every other ecosystem in this table joins with a slash, because that is what its names look like in the wild: an npm scope reads at-scope slash name, a Go module path reads github.com slash owner slash repo. So joining a Maven coordinate the same way produces a name that is correctly assembled and still matches nothing.

What is a package URL, and why prefer it as the canonical spelling?

A package URL, usually written purl, states a registry, a name and a version in one string. It is the identifier the SBOM formats themselves carry, which is why it is used as the canonical spelling wherever the two inputs disagree. Its qualifiers and subpath are dropped before matching: an architecture or a subdirectory narrows which build is being described, not which package is named, so carrying them into the comparison would only invent mismatches.

Why does my advisory export say Alpine colon v3.19 when my SBOM just says alpine?

OSV qualifies some ecosystems with a distribution release. The qualifier narrows which advisories apply, not which package is named, so it is dropped at the colon before matching. Keeping it would mean a plain alpine in an SBOM could never match an advisory for the release that SBOM was built from, which is the opposite of what the qualifier is there to express.

If names are normalised, is the tool guessing at matches?

No, and the distinction is the whole coverage boundary. Folding two spellings of the same registry onto one is reading what both files already state. Inferring is deciding something neither file says. This tool does the first and never the second: it does not resolve aliases, affected version ranges, reachability, or exploitability. An advisory that expresses affected versions only as a range therefore contributes no match at all, and is reported as not evaluated rather than dropped, because a clean result means something very different when part of the export was never assessed.

One entry in my SBOM is malformed. Is the whole file rejected?

No. A package URL that cannot be parsed is skipped rather than raised, and that component's own name, ecosystem and version fields are read instead. A single bad entry among two thousand good ones should not cost you the file, and a component that states usable coordinates some other way is still matched on those.

Want the comparison done for you? CRA Evidence Desk folds both spellings onto one, matches your SBOM against your advisory export on exact name, ecosystem and version, and names the advisories it could not evaluate. It runs entirely in your browser, your SBOM is never uploaded, and it is free.