RedMirror Reflection is now the default way to use RedMirror — one offline binary that gives your own coding agent the power to find real bugs and prove them, right on your machine. Get started →
Availability Fixed · moved to osv-scalibr Go · supply-chain tooling

A single unknown ecosystem could abort an entire osv-scanner offline scan

Targetosv-scanner (Google)
ClassPanic → whole-scan abort
Triggeradvisory with an unknown ecosystem
ReportedIssue #2867
FixedPR #2882 (approved)
Movedosv-scalibr PR #2429 (matcher relocated)

In Google's osv-scanner, a single OSV advisory carrying an ecosystem name the pinned schema didn't recognize would panic the matcher and abort the entire offline scan, not just skip that advisory. Because osv.dev adds ecosystems over time, an older binary hits this in normal use. PR #2882 fixes it by skipping unknown ecosystems instead of crashing; the matcher has since moved to osv-scalibr, where the same fix is PR #2429.

osv-scanner is Google's open-source vulnerability scanner. It matches the dependencies in your project against advisories from the OSV database, and in offline mode it runs entirely against a local copy of that database, the mode you reach for in air-gapped environments and reproducible CI builds.

We found that a single OSV advisory carrying an ecosystem name the scanner didn't recognize would panic the matcher and abort the entire scan. Not skip one advisory, not warn: crash the whole run.

One advisory whose ecosystem string isn't in your build's pinned schema, and the scan of every package stops with a panic.

Why does MustParse panic on an unknown ecosystem?

Deep in the matcher, vulns.IsAffected and vulns.AffectsEcosystem resolved an advisory's ecosystem with osvecosystem.MustParse. As the name says, MustParse panics on any string the vendored osv-schema registry doesn't recognize:

// matcher, before the fix
eco := osvecosystem.MustParse(advisory.Ecosystem)   // panics on an unknown ecosystem
// ...one unrecognized advisory here aborts the whole scan

Here's why that is reachable in normal operation, not a contrived input: the OSV database on osv.dev adds new ecosystems over time, while any given osv-scanner binary is built against a pinned snapshot of the schema. The day the database ships an advisory for an ecosystem newer than your installed scanner knows about, that advisory's ecosystem string is “unknown” to MustParse, and the panic takes the entire offline scan down with it.

Why does this matter for a security tool?

The failure mode is the worst kind for a scanner. It doesn't quietly miss one advisory; it aborts the whole run. A CI gate that depends on osv-scanner to fail the build on a known-vulnerable dependency simply stops producing a verdict the moment an unrelated new ecosystem lands upstream, and offline, reproducible builds are precisely where you can't just pull a fresh schema to make the crash go away. A robustness bug in the tool becomes a gap in the thing the tool exists to guarantee.

How was it fixed?

PR #2882 (maintainer-approved), addressing issue #2867, replaces the panic-prone call with a parseAffectedEcosystem helper built on the non-panicking osvecosystem.Parse. When an ecosystem isn't recognized, the affected entry is skipped with a debug-level log instead of crashing, mirroring the error handling the scanner already used for version parsing.

Update, September 2026. Before #2882 merged, osv-scanner moved its local matcher into osv-scalibr, and the maintainer asked for the PR to follow. The same fix, with the regression test, is now osv-scalibr PR #2429. The panic site (osvecosystem.MustParse in IsAffected) was carried over unchanged in the move, so the bug is still live in osv-scalibr until that PR lands.

// after the fix
eco, err := osvecosystem.Parse(advisory.Ecosystem)
if err != nil {
    // skip this affected entry, keep scanning
    log.Debug(...); continue
}

The practical effect: older builds now gracefully skip the entries they can't interpret instead of aborting all offline scans when osv.dev moves faster than the pinned schema.

Why is this the kind of bug RedMirror finds?

A scanner is a state machine over its inputs, and its inputs include the advisory data it's asked to interpret. Feed it something just outside its modeled domain (an ecosystem that isn't in the pinned enumeration), and the correct behavior is to degrade, not halt. RedMirror looks for exactly that: a reachable input that drives a program into a state it has no graceful path out of. Here it's an advisory field with an unrecognized value reaching a MustParse that treats “unknown” as “impossible.” We surface the input that gets there so it can be handled before it takes a scan down in production.

Frequently asked questions

What bug did RedMirror find in osv-scanner?

In Google's osv-scanner, a single OSV advisory carrying an ecosystem name the scanner didn't recognize would panic the matcher and abort the entire offline scan. It did not skip the one advisory or warn, it crashed the whole run.

Why would an unknown ecosystem reach osv-scanner in normal operation?

The OSV database on osv.dev adds new ecosystems over time, while any given osv-scanner binary is built against a pinned snapshot of the schema. The day the database ships an advisory for an ecosystem newer than your installed scanner knows about, that string is unknown to MustParse, and the panic takes the entire offline scan down.

Why does this matter for a security tool?

The failure mode is the worst kind for a scanner: it aborts the whole run instead of quietly missing one advisory. A CI gate that relies on osv-scanner to fail the build on a known-vulnerable dependency stops producing a verdict the moment an unrelated new ecosystem lands upstream, and offline reproducible builds are exactly where you cannot just pull a fresh schema to make the crash go away.

Is the osv-scanner panic fixed?

Yes. PR #2882 (maintainer-approved, addressing issue #2867) replaces the panic-prone MustParse call with a parseAffectedEcosystem helper built on the non-panicking osvecosystem.Parse. The matcher has since moved to osv-scalibr, so the fix was re-submitted there as osv-scalibr PR #2429. An unrecognized ecosystem is now skipped with a debug-level log instead of crashing the scan, mirroring the error handling the scanner already used for version parsing.

Update, September 2026. Before #2882 merged, osv-scanner moved its local matcher into osv-scalibr, and the maintainer asked for the PR to follow. The same fix, with the regression test, is now osv-scalibr PR #2429. The panic site (osvecosystem.MustParse in IsAffected) was carried over unchanged in the move, so the bug is still live in osv-scalibr until that PR lands.

What language is osv-scanner written in?

Go. osv-scanner is Google's open-source vulnerability scanner, and the panic lived in its matcher, where vulns.IsAffected and vulns.AffectsEcosystem resolved an advisory's ecosystem with osvecosystem.MustParse.

How did RedMirror find this bug?

RedMirror treats a scanner as a state machine over its inputs and looks for a reachable input that drives the program into a state it has no graceful path out of. Here it surfaced an advisory field with an unrecognized ecosystem value reaching a MustParse that treats unknown as impossible, so it can be handled before it takes a scan down in production.

Audit the tool, not just the code it scans

Parsers, matchers, and anything that consumes external data have states like this: an input the code assumed could never appear. RedMirror finds the reachable one and reports it as a concrete path, so a robustness gap doesn't become a security gap.

Get RedMirror Read the docs