The same CVE appears many times in an SCA report because the report counts occurrences, not unique problems. A package can be reachable through several dependency paths, present in several versions, installed in several projects, or recorded under more than one identifier. Deduplicate by vulnerability and package version to see the real count.
Five reasons for repeats
- Multiple paths. Two direct dependencies both pull in the same vulnerable library. Some tools list one row per path.
- Multiple versions. Package managers can install several versions of the same package side by side. Each affected version can show as its own finding.
- Multiple projects. A monorepo has one lockfile per service. The same library shows up in each.
- Multiple identifiers. One flaw can have a CVE ID, a GitHub advisory ID and an ecosystem ID.
- Multiple scans merged. Reports that combine results from different scans or branches can include the same finding twice.
Identifiers and aliases
The OSV schema has an aliases field that lists IDs of the same vulnerability in other databases. It defines two vulnerabilities as aliases if they affect any given software component the same way, either both affect it or neither do, and a subsequent patch addresses both and no others. Aliases are symmetric and transitive.
That means a CVE ID and an advisory ID for the same flaw can be safely merged. The schema also has a related field for vulnerabilities that are similar but not strictly aliases, and those should not be merged. Related is a looser link than alias.
| Field | Meaning | Merge in your count? |
|---|---|---|
| Aliases | Same vulnerability, another database ID | Yes |
| Related | Similar but different vulnerability | No |
| Upstream | Vulnerability in an upstream package | Treat as linked, review separately |
How to deduplicate
- Choose a key. A good one is vulnerability ID plus package name plus package version.
- Collapse aliases to one ID before counting.
- Count unique keys for the headline number and keep the occurrence count for effort estimates.
- Group by fix, so one upgrade covers several keys.
Two numbers are useful and both are honest: unique vulnerabilities, and unique places to change. The first tells you about exposure, the second about workload.
A quick example
A report shows 30 rows for 6 CVE IDs. Four IDs are aliases of two others, leaving 4 unique vulnerabilities. Three affect one library that appears in five services at the same version. The library needs one version bump per service, so the workload is five changes, not 30 rows.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how findings are grouped instead of listed one row per occurrence.
Where Safeguard fits
Safeguard's dependency scanning and vulnerability management group findings so you can work from the change needed rather than the row count.
Quick check
Should I merge a GitHub advisory ID with a CVE ID?
If the database lists them as aliases, yes. They describe the same vulnerability. Related IDs are different issues and should stay separate.
Which count do I report to leadership?
Report unique vulnerabilities for exposure and unique changes for workload. Raw row counts mislead in both directions.
Sources
Last reviewed: 19 October 2026.