A scan lists one flaw twice when different databases gave it different IDs, such as a CVE and a GHSA, and the tool did not merge them. The OSV format links those records with an aliases field. Group findings by component plus alias set and you get one row per real problem.
Why one flaw gets several IDs
No single registry owns every advisory. A CVE record comes from the CVE program. A GitHub advisory gets a GHSA ID. An ecosystem database may add its own ID. Each is a separate record, written by a different team, sometimes on a different day.
The OSV schema handles this with an aliases field. It lists the IDs of the same vulnerability in other databases. The schema says aliases are symmetric (if A is an alias of B, B is an alias of A) and transitive (if A aliases B and B aliases C, A aliases C). That makes them easy to merge: build groups where any shared alias joins two records.
Three fields that are easy to confuse
| Field | What it means | Merge into one finding? |
|---|---|---|
| aliases | The same vulnerability in another database | Yes |
| upstream | The record describes a vulnerability that comes from another record, such as a library flaw packaged by a distribution | No, keep both, but link them |
| related | Closely related, such as a similar but different flaw | No |
The schema is explicit that aliases should not be used across the supply chain. If a distribution bundles a library and publishes its own advisory, that record should not list the library CVE as an alias. It uses the upstream field instead. So two rows that look alike may be one flaw or two separate records you should still read.
How to deduplicate a report, step by step
- Export findings with the component name, version and every ID on each record.
- Normalize the component identifier first. Two rows for different spellings of one package will never merge. See purl or CPE for identifier choices.
- Within each component, join records that share any alias.
- Show one row per group, and keep all IDs visible so people can search by whichever one they have.
- Keep upstream links as a note, not a merge.
- Take the highest severity and the earliest fixed version across the group only after reading why they differ.
What to check when scores differ
Merged records can disagree on severity or on the fixed version. That is normal, since different editors scored the flaw at different times. Treat a disagreement as a prompt to read the advisory text, not as proof that one is wrong. The CVSS inconsistency post covers why scores drift.
Also watch for the opposite problem. If two records for different flaws share a component, do not merge them just because they look alike. Only merge on a shared alias, not on similar titles.
Try it yourself
Click through it at your own pace, or open it full screen.
Open a finding and look at its identifiers. Notice how one issue can be tracked under a single row with the other IDs attached.
Quick check
Is a GHSA ID the same as a CVE ID?
No. They are different records. They describe the same flaw when one lists the other as an alias, and tools should then show them as one finding.
Should a distribution advisory be merged with the library CVE?
Not as an alias. The OSV schema uses the upstream field for that link, so keep both records and show the relationship.
Why do I still see two rows after merging by alias?
The component identifiers probably differ, for example two spellings or two ecosystems. Fix the identifier first, then merge.
Safeguard offers dependency scanning with SBOM output and reachability analysis, and the free scan lets you try it on your own project.
Sources
Last reviewed: 19 October 2026.