Safeguard
Supply Chain•

OSV version ranges explained: introduced and fixed events

How OSV records affected versions with introduced and fixed events, and how to read a range to decide whether your installed version is vulnerable.

Safeguard Security Team
3 min read

An OSV record marks affected versions with events. An introduced event says where a flaw begins, and a fixed event says where it ends. A version before the fixed value, and at or after the introduced value, is affected. Introduced zero means affected from the very first release.

What OSV is

OSV, short for Open Source Vulnerabilities, describes itself as a distributed vulnerability database for open source. It aggregates advisories from other databases that use the OSV schema, including GitHub Security Advisories, PyPA and RustSec. At the time of fetching, the site lists 38 ecosystems, including npm, PyPI, Maven and Go.

A distributed design means no single organisation owns every advisory, and the shared schema lets one tool read all of them.

Reading an events list

The site's own example shows a range with introduced: "0" and fixed: "1.25.0". That means every version before 1.25.0 is affected. Version 1.25.0 and later are not.

Here is the logic:

  1. Start unaffected.
  2. At an introduced event, versions from that point onward become affected.
  3. At a fixed event, versions from that point onward become unaffected again.

A record can hold several pairs. For example, a flaw introduced in 2.0, fixed in 2.3, and then reintroduced in a later branch would have two ranges. Always read all events, not just the first.

Version schemes matter

The site notes that ranges can use SEMVER, and advisories may also map to commit hashes. Not every ecosystem orders versions the same way. A package manager's own comparison rules decide whether one version is before another, so a scanner should use the right scheme for each ecosystem. If you compare version strings by hand, pre-release tags and epoch prefixes are easy to get wrong.

Querying

You can query by package name, ecosystem and version, or by commit hash. A practical use is to take a package from your lockfile and ask whether that exact version is affected. The record also tells you the first fixed version, which is the smallest upgrade that clears that advisory.

Common mistakes

Assuming the fixed version is always the best upgrade. It is the first version that clears one advisory. Later versions may be needed for others, and a jump across a major version can break your build.

Treating no match as safe. No match means no advisory in that database for that version. Brand new flaws, or flaws in packages outside the ecosystems covered, will not show up.

Ignoring the difference between a package being present and a flaw being reachable. A vulnerable function you never call is lower priority than one on a hot path, which is where reachability analysis helps.

Where it fits in a workflow

Matching ranges is the first filter. After that, add exploitation signals. See the post on prioritising with KEV, EPSS and reachability for the second step.

Where Safeguard fits

Safeguard's dependency scanning and reachability analysis automate this matching and the follow-up question of whether your code calls the flawed code. The free scan at gold.safeguard.sh/scan lets you try it on a manifest.

Quick check

What does introduced zero mean?

The flaw is present from the earliest version, so everything before the fixed version is affected.

Is the fixed version always the right upgrade?

It is the first version clearing that advisory. Check for other advisories and for breaking changes.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.