A lockfile gives a more accurate scan because it records the exact versions resolved. A manifest usually declares ranges, so a scanner must guess which version you run. Use a lockfile or a built artifact when you can, and treat manifest only results as best effort.
The difference in one table
| Input | What it records | Accuracy for matching |
|---|---|---|
| Manifest (for example package.json, requirements.txt, pom.xml) | What you asked for, often as a range | Estimate |
| Lockfile | What the package manager resolved | Exact for the file's date |
| Installed environment or built image | What is really present | Exact for that build |
OSV-Scanner's documentation says it plainly: manifest files can declare version ranges and do not necessarily record the versions installed in an environment, so versions read from them are best effort and may not match what is installed. It advises preferring a resolved lockfile.
What a scanner does with a range
Given foo >= 2.0, a tool might do any of these:
- Assume the lowest version in the range and report the oldest flaws, possibly too many.
- Assume the latest version and report too few.
- Resolve the range against a registry at scan time, which is slow and changes from day to day.
- Skip it and say nothing.
Each gives a different result for the same file. A pinned manifest entry avoids the problem for direct dependencies, but not for transitive ones, which a manifest does not list at all.
When a manifest is all you have
Sometimes you only receive a manifest, for example in an acquisition review or a supplier handoff. In that case:
- Label the result as an estimate in the report.
- Ask for the lockfile or an SBOM from the build.
- Run the scan again when you have it and compare. A large difference tells you how much the estimate was worth.
- Do not use the manifest result to make a release decision.
For the full list of what manifest only scanning misses, see what manifest only dependency scanning misses, and for the file choice by ecosystem see which file to scan: package.json, requirements.txt or an SBOM.
Make it automatic
- Commit lockfiles for applications.
- Scan on the lockfile in pull requests and on the built artifact at release.
- Fail the job if the scan finds zero components in a project you know has dependencies.
- Record the input type in each report, so reviewers know what they are reading.
Safeguard's SBOM and dependency scanning supports lockfiles and built inputs, and you can try either with the free scan at https://gold.safeguard.sh/scan.
Try it yourself
Open the demo and look at the component list. Each entry has a concrete version, which only a resolved input can supply.
Click through it at your own pace, or open it full screen.
Quick check
Is a requirements.txt without pins enough for an accurate scan?
No. Without exact versions the scanner has to estimate, and transitive packages are not listed.
Should libraries commit a lockfile?
It helps for your own testing and scanning, but consumers resolve their own versions, so also scan the dependency ranges you publish.
Sources
Last reviewed: 19 October 2026.