Cut false positives by sorting them by cause, because each cause has a different fix: wrong package matching, vulnerable code your app never calls, findings in test or dev scope, and stale data. Then record every dismissal with a reason, ideally as a VEX statement, so the same alert does not come back.
"False positive" covers two different things. A finding can be wrong, meaning the product is not affected. Or it can be right but irrelevant to your risk. Mixing them leads to bad decisions, so this guide separates them.
Which findings are actually wrong?
These are matching errors. The tool says package X is vulnerable, and it is not.
- Name or version mismatch. The advisory names a product and the scanner guessed the wrong package, or compared against the wrong version range.
- Backported fixes. A distribution may patch a library without changing the version number, so a version-based match reports a flaw that is already fixed. Check the distributor's advisory for the package before dismissing.
- Duplicate or renamed packages. The same code appears under two names.
The fix is evidence. Check the exact package, the version in your lockfile or image, and the advisory's affected range. If the tool was wrong, report it to the vendor with that evidence. Repeated mistakes are a quality signal you can use in a trial.
Which findings are real but do not apply?
This is the biggest bucket in most programs and the one where reachability matters. A vulnerability in a library function your code never calls is real in the library and often not exploitable in your application.
Safeguard's documentation describes reachability in three forms. Static reachability builds a call graph from your source and lockfile to see whether a path leads to the vulnerable code. Dynamic reachability observes what runs. Configuration reachability checks whether the code is wired in at all. It labels results reachable, conditionally reachable, unreachable or unknown, and treats unknown conservatively as potentially reachable. That last choice is the right one: when an analyzer cannot decide, it should not claim safety.
Open the exploitability check demo in its own page.
Which findings are in the wrong scope?
A flaw in a test-only or build-only dependency does not ship to production. Tag assets by environment and exposure. CISA's BOD 26-04, which governs US federal agencies, asks whether the vulnerable asset is publicly exposed, whether the CVE is on the KEV list, whether the exploit can be fully automated, and whether it gives partial or total control. Private companies are not bound by it, but those four questions are a good filter for scope.
Which findings come from stale data?
Fixed issues that stay open, closed advisories, and findings on assets that no longer exist. Tie scans to the artifact you deploy, rescan after each release, and retire assets when they are decommissioned.
How do you record a dismissal so it sticks?
Use a structured statement. OpenVEX defines a statement as a product, a vulnerability and a status. For a not-affected status, the spec says the statement must include either a justification label or an impact statement explaining why. One of the labels is "vulnerable code not in execute path." CISA describes VEX as an attestation that a product is or is not affected. Writing dismissals this way gives auditors evidence and stops the same alert returning.
What are the limits of cutting noise?
Reachability analysis can miss dynamic behavior such as reflection or plugin loading, which is why unknown must stay cautious. Suppression without expiry becomes a hiding place. And a low alert count can mean a scanner that failed to run, not a clean codebase. Track scanner coverage as carefully as findings.
What to do
- Sample twenty recent dismissed findings and label each: wrong match, not reachable, wrong scope or stale.
- For wrong matches, verify against the advisory and send evidence to the vendor.
- Turn on reachability analysis and keep unknown results visible.
- Add environment and exposure tags to assets.
- Record every dismissal with a reason, an owner and an expiry date.
- Rescan on each release and when new KEV entries match your components.
Quick check
Is an unreachable vulnerability a false positive?
Not exactly. The flaw exists in the library, but your code may not trigger it. Treat it as lower priority and record why, instead of deleting the finding.
What should a not-affected dismissal include?
A reason. In OpenVEX, a not-affected statement needs a justification label or an impact statement, plus the product and vulnerability it covers.
Sources
- OpenVEX specification
- CISA, Software Bill of Materials (SBOM) and VEX
- CISA, BOD 26-04: Prioritizing Security Updates Based on Risk
- Safeguard vulnerability prioritization and reachability
Last reviewed: 18 October 2026.