How to Use OSV-Scanner: The Beginner's Guide (First Scan, the V2-Syntax Lesson, the Fix Lesson, and the CI Habit)

CodexFuse Team · 2026-11-01T12:29:45.220Z · 19 min read

Learn how to use OSV-Scanner: install v2.7.0, master the V2 subcommand syntax, run your first source and image scans, read every output format, use guided fixes, and automate it in CI.

This guide teaches you how to use OSV-Scanner, Google's open-source command-line tool that checks your project's dependencies against the OSV.dev vulnerability database. If you ship code with open-source libraries in it — and nearly everyone does — OSV-Scanner tells you, in one command, which of those libraries have known security vulnerabilities, and which versions fix them. The tool is small, free, and works on any project with a lockfile or a git history. This osv-scanner tutorial walks you from a fresh install to your first scan, your first container image scan, guided fixes, and a CI habit that keeps you covered forever.

Two things to know up front. First, OSV-Scanner is a developer tool that runs on your own machine or in your CI pipeline — there is no web app to sign up for. If you plan to run the container-image scans in a container, make sure Docker is installed first; our Docker beginner guide covers that setup. Second, the current release is v2.7.0 (October 2026), and version 2 changed the command syntax in a way that breaks old tutorials — this guide is written for V2 only, and it calls out exactly which commands the old V1 tutorials taught you to stop using.

What is OSV-Scanner?

OSV-Scanner is Google's open-source command-line vulnerability scanner for project dependencies. It reads your project's lockfiles, SBOMs (software bills of materials), or git history, looks up every pinned dependency version in the OSV.dev database of known vulnerabilities, and prints a report showing which dependencies are affected and which fixed versions are available. Unlike scanners that require uploading your code to a cloud service, OSV-Scanner runs locally: the lookups go to the public OSV.dev API (or a local database copy), and your source code never leaves your machine. The project lives at github.com/google/osv-scanner, is licensed Apache-2.0, and has more than 11,000 stars as of late 2026.

The database it queries is the OSV.dev project, a distributed vulnerability database that aggregates advisories from many ecosystems (npm, PyPI, Go, Maven, crates.io, RubyGems, and more) into one queryable format. OSV-Scanner is the official frontend for it: one install, and you can check dependencies across 11+ ecosystems and 19+ lockfile types without per-ecosystem tooling. You will also see the tool called the "google osv scanner" in search results — that is the same product, Google's OSV-Scanner, and this osv.dev tutorial covers it end to end.

The V2 syntax lesson: forget the old bare-flag commands

In OSV-Scanner V2, every scan goes through a subcommand: osv-scanner scan source for project directories and osv-scanner scan image for container images. Version 2.0.0 (March 2025) rebuilt the tool on OSV-SCALIBR, Google's new extraction library, and replaced the old V1 bare-flag style with explicit subcommands. This is the single biggest source of confusion online: the old V1 documentation page still ranks on Google, and many third-party tutorials still teach V1 commands. They will not work the way you expect on the current release.

The old commands you will see in stale tutorials, and their V2 replacements, are:

Old V1 command (do not use)V2 replacement
osv-scanner --recursive ./osv-scanner scan source -r ./
osv-scanner --docker nginx:latestosv-scanner scan image nginx:latest
osv-scanner --sbom sbom.jsonosv-scanner scan source --sbom sbom.json
osv-scanner --skip-git ./osv-scanner scan source --no-ignore ./ (see the .gitignore section)

The rules are simple: bare osv-scanner with no subcommand behaves like scan source, image scanning moved to its own scan image subcommand, and anything starting with --experimental- is deprecated — the renamed flags now use the --x- prefix (for example, --x-exclude). Whenever a tutorial shows you a V1 flag, translate it with the table above before running it.

How to install OSV-Scanner

The recommended install is the prebuilt binary from the GitHub releases page; every release ships SLSA3-signed binaries, so you can verify what you downloaded. Pick your lane from the options below — no matter which osv-scanner install path you choose, all of them install the same current release, v2.7.0.

Your situationInstall command
macOS with Homebrewbrew install osv-scanner
Linux with pacman / apkpacman -S osv-scanner or apk add osv-scanner
Windows with WinGet or Scoopwinget install Google.OSVScanner or scoop install osv-scanner
Go installed (1.26.2 or newer)go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest
No Go, no package manager — or CIDownload the binary for your OS from github.com/google/osv-scanner/releases
No install at alldocker run ghcr.io/google/osv-scanner:latest scan source /path

The quickest way to get running, regardless of platform, is the prebuilt binary lane:

  1. Open github.com/google/osv-scanner/releases and download the v2.7.0 archive for your operating system and architecture.
  2. Verify the download against the published SLSA provenance attestation (linked from the release page) if you want cryptographic proof it came from Google's build.
  3. Extract the osv-scanner binary and move it somewhere on your PATH, such as /usr/local/bin on Linux/macOS.
  4. Run osv-scanner --version and confirm it prints osv-scanner version: 2.7.0 (or newer).

Installing the binary does not start any service and nothing listens on any port — OSV-Scanner is a plain CLI that runs, reports, and exits. The only network it touches by default is the OSV.dev API when it looks up vulnerabilities.

Your first scan: osv-scanner scan source

osv-scanner scan source -r ./ is your first scan: it walks a directory recursively and checks every dependency it can identify against OSV.dev. Change into a project directory and run it. Here is the full first-scan arc, end to end:

  1. Open a terminal and cd into your project directory — the one holding your lockfile (package-lock.json, requirements.txt, go.mod, Cargo.lock, Gemfile.lock, and so on).
  2. Run osv-scanner scan source -r ./. The -r (--recursive) flag walks subdirectories; without it only the top level is scanned.
  3. Watch what it finds automatically. The scanner picks up lockfiles, SBOM files (SPDX and CycloneDX), and git directories on its own — you do not tell it which ecosystem you use. Across the supported ecosystems it recognizes 19+ lockfile types.
  4. Read the table. The default output is a human-readable table: package name, the vulnerable version range, the fixed version, and the advisory ID (for example, an OSV or GHSA ID). Each row is one known-vulnerable dependency.
  5. Note the exit code. OSV-Scanner exits non-zero when it finds vulnerabilities — that is by design, so CI pipelines can gate on it.
  6. If it found nothing, congratulations: your pinned versions are clean as of today's database. Re-run the scan after you update dependencies, because new advisories are published every day.

One extra capability worth knowing: when scanning Go source, OSV-Scanner uses the govulncheck library to analyze which vulnerable functions your code actually calls — this deeper call analysis is on by default and needs the go toolchain on your PATH. Rust call analysis exists but is experimental.

The .gitignore gotcha: why your vendored code is invisible

OSV-Scanner respects your .gitignore by default and skips ignored files silently — which means vendored dependencies under an ignored directory are never scanned. This is the behavior that surprises people most: you scan a repo, get a clean report, and assume everything is covered, while the vendored copy of an old library sitting in an ignored vendor/ or third_party/ folder never made it into the report.

The fix is the --no-ignore flag: osv-scanner scan source -r --no-ignore ./ scans everything, including git-ignored paths. Use it whenever you scan vendored code, generated folders, or build output directories. There is also --x-exclude (note the V2 --x- prefix) to exclude specific directories, for example --x-exclude=test to skip your test fixtures.

Scanning container images: osv-scanner scan image

osv-scanner scan image nginx:latest scans a container image layer by layer, thanks to the V2 rebuild on OSV-SCALIBR. The V2 image scanner understands Alpine, Debian, and Ubuntu base images plus Go, Java, Node.js, and Python artifacts inside the layers, so it finds vulnerabilities in both the OS packages and the application dependencies baked into the image.

Two practical notes. First, the scan image subcommand shells out to the docker CLI (it runs docker save into a temporary archive, never executing anything from the image), so Docker must be installed and on your PATH — if you do not have it yet, see our Docker beginner guide. To scan an image archive file directly instead, pass --archive image.tar. Second, you cannot mix targets: one scan image call takes exactly one image.

How does this differ from Trivy? They are sibling tools, not rivals: Trivy scans images, filesystems, repos, and misconfigurations with zero config; OSV-Scanner's scan source lane goes deeper on lockfile and SBOM-first dependency checking via OSV.dev, and its fix lane offers guided remediation. If image scanning is your main job, read our Trivy beginner guide too — the draw-the-line rule is simple: Trivy for broad image-and-config coverage, OSV-Scanner for OSV.dev-native dependency precision and the fix workflow below.

Reading the report: output formats and the HTML server

Use --format to change the report shape; --serve opens it as a browsable HTML page on port 8000. The default table format is for humans; the machine formats are for pipelines:

FormatCommandUse it for
table (default)scan source -r ./Reading results yourself
vertical / markdown--format vertical / --format markdownPasting into tickets and docs
json--format json --output-file report.jsonScripts and dashboards
sarif--format sarifGitHub Code Scanning uploads
spdx / cyclonedx--format spdx / --format cyclonedxSBOM export for compliance
html--format html or --serveBrowsable report (--serve serves it on port 8000)

The SARIF lane matters: GitHub Advanced Security accepts SARIF uploads into the Code Scanning tab, so a --format sarif report plugs straight into the security dashboard your team already watches. We use it in the GitHub Actions section below.

The fix lesson: osv-scanner fix (npm and Maven only)

osv-scanner fix proposes and applies version bumps for vulnerable dependencies — but it only supports npm and Maven, and it is experimental. Say that scope plainly, because the name suggests a universal fixer and it is not one: on a Node project it rewrites package-lock.json in place (or re-locks from package.json), and on a Maven project it adds overrides to pom.xml. Every other ecosystem — Go, Python, Rust, Ruby, and the rest — gets scan-only support; you upgrade those by hand.

The two lanes in practice:

osv-scanner fix -M "package-lock.json:/path/to/project"
osv-scanner fix -M "pom.xml:/path/to/project"

One warning the documentation states explicitly: the fix command can execute package-manager scripts as a side effect of relocking, so do not run it on untrusted projects. Scan first, review the proposed changes, and run fix only on code you trust. After applying a fix, re-run scan source to confirm the report is clean.

Offline scanning: when the network is off-limits

OSV-Scanner can scan fully offline once you have downloaded the vulnerability databases to your machine. Air-gapped build servers and compliance-sensitive environments use this lane: set OSV_SCANNER_LOCAL_DB_CACHE_DIRECTORY to point at a cache directory, pre-fill it with osv-scanner --download-offline-databases, and then scan with --offline for fully offline operation. If you only want the vulnerability data local while letting other features use the network, --offline-vulnerabilities is the middle lane.

You can also fetch databases manually from gs://osv-vulnerabilities/<ECOSYSTEM>/all.zip for each ecosystem you need. One limitation to know: commit-level scanning (checking vulnerabilities at a specific git commit) is not supported in offline mode — offline matching works on pinned versions from lockfiles and SBOMs.

OSV-Scanner pre-commit: catching issues before the commit

Add OSV-Scanner to your pre-commit hooks and it scans your changes before every commit lands. The project ships two hooks, osv-scanner (native binary) and osv-scanner-docker (container, for machines without the binary), served from github.com/google/osv-scanner/. Add this to your .pre-commit-config.yaml:

- repo: https://github.com/google/osv-scanner/
  rev: v2.7.0
  hooks:
    - id: osv-scanner
      args: ['scan', 'source', '--format=vertical', '--verbosity=error', '--recursive', '.']

Pin the hook to the current release (v2.7.0 at the time of writing — the documentation examples pin older revs like v2.3.3, so update the pin when you copy them). The --verbosity=error keeps the output quiet unless something is actually vulnerable, which keeps pre-commit fast and non-annoying. A failed scan blocks the commit until you fix or explicitly bypass it — that is the point.

OSV-Scanner GitHub Actions: the CI habit

The google/osv-scanner-action repository provides two reusable workflows: a pull-request differential scan and a full scan for pushes, schedules, and releases. The differential workflow (osv-scanner-reusable-pr.yml) only reports vulnerabilities introduced by the PR — perfect for keeping new code clean without drowning in pre-existing findings. The full workflow (osv-scanner-reusable.yml) scans everything on push, on a schedule, or at release time.

jobs:
  scan:
    uses: google/osv-scanner-action/.github/workflows/[email protected]

Pin the action to the current release tag (@v2.7.0); combine it with the SARIF output format and the workflow uploads results to GitHub Code Scanning, so findings appear as alerts on the pull request. If you are new to CI, our GitHub beginner guide walks through repositories, Actions, and pull requests from the beginning.

7 beginner mistakes to avoid

MistakeWhat happensThe fix
Copying V1 commands from old tutorials--recursive, --docker, --sbom do not work as V2 subcommandsUse scan source / scan image per the table above
Scanning without -rOnly the top-level directory is checked; nested projects are missedosv-scanner scan source -r ./
Forgetting the .gitignore defaultVendored dependencies are silently skippedAdd --no-ignore when scanning vendored code
Using --experimental-* flagsDeprecated in v2.7.0; may be removedUse the --x-* aliases (--x-exclude)
Expecting fix to work on every languageGo/Python/Rust projects get no remediationfix is npm + Maven only; upgrade others manually
Running fix on an untrusted repoPackage-manager scripts can execute during relockReview diffs; run fix only on trusted code
Never re-scanningNew advisories appear daily; a clean scan ages fastAutomate with pre-commit + scheduled GitHub Actions

Sources

  • OSV-Scanner releases (v2.7.0, 2026-10-12; v2.0.0, 2025-03-17) and repository stats (11,344 stars, Apache-2.0) — api.github.com/repos/google/osv-scanner/releases and github.com/google/osv-scanner
  • V2 subcommand syntax (scan source, scan image, fix) — google.github.io/osv-scanner/usage/
  • Installation methods (binaries, go install, brew/pacman/apk/scoop/WinGet, Docker) — google.github.io/osv-scanner/installation/
  • Scan-source behavior (lockfiles, SBOMs, git dirs, -r, .gitignore default, --no-ignore, --x-exclude) — google.github.io/osv-scanner/usage/scan-source
  • Go govulncheck call analysis (on by default, needs go on PATH; Rust experimental) — google.github.io/osv-scanner/usage/scan-source
  • Scan-image behavior (OSV-SCALIBR layer awareness, docker save requirement, --archive) — google.github.io/osv-scanner/usage/scan-image
  • Fix command scope (npm + Maven, experimental, untrusted-project warning) — github.com/google/osv-scanner
  • Output formats (table, markdown, vertical, html, json, sarif, spdx, cyclonedx) and --serve port 8000 — google.github.io/osv-scanner/output/
  • Offline mode (cache directory env var, --offline, --offline-vulnerabilities, --download-offline-databases, commit-level limitation) — google.github.io/osv-scanner/usage/offline-mode/
  • Pre-commit hooks (hook IDs, example args, rev pinning) — google.github.io/osv-scanner/usage/
  • GitHub Actions reusable workflows (PR differential + full, SARIF to Code Scanning) — google.github.io/osv-scanner/github-action/
  • V2.0.0 rebuild on OSV-SCALIBR and Maven guided remediation — ssojet.com/blog/google-osv-scanner-v2-elevating-open-source-vulnerability-management

Frequently asked questions

Is OSV-Scanner free?

Yes. OSV-Scanner is open source (Apache-2.0) and free to use, and the OSV.dev vulnerability database it queries is a free public service run by Google. There is no signup, no API key, and no paid tier.

What is the difference between OSV-Scanner V1 and V2?

V2 (released March 2025) rebuilt the tool on OSV-SCALIBR and replaced the V1 bare-flag syntax with subcommands: scan source, scan image, and fix. Old commands like osv-scanner --recursive ./ or osv-scanner --docker img are the V1 style; translate them with the mapping table in the V2 syntax section of this guide.

Does OSV-Scanner upload my code anywhere?

No. It extracts package names and versions locally and queries only those against the OSV.dev API (or a local database copy in offline mode). Your source code never leaves your machine, which is why teams in regulated environments use it.

Can OSV-Scanner fix vulnerabilities automatically?

Partially. osv-scanner fix is experimental and supports only npm and Maven projects. For every other ecosystem it tells you which versions are fixed and you apply the upgrade yourself. Never run fix on a project you do not trust, because package-manager scripts can execute during the relock.

OSV-Scanner vs Trivy — which should I use?

Use both for different jobs. Trivy covers images, filesystems, repos, and misconfigurations with zero config — see our Trivy beginner guide. OSV-Scanner is the OSV.dev-native lane: deeper lockfile/SBOM-first dependency checking, the npm/Maven guided-fix workflow, and a scanner that fits neatly into pre-commit hooks and GitHub Actions without a daemon.

Featured on Twelve Tools Launch Llama Tools Launch your MCP