Use Gradle dependency locking when your build uses dynamic versions such as 5.x or a range, and you want the same resolved versions every time. Gradle writes the resolved result to a lock file and fails the build if resolution would differ. It pins versions. It does not check file contents.
What locking does
Gradle's documentation explains the problem. A declaration like a plus-style version means the exact version resolved can change over time, which can break builds without any change in your code. Locking records the resolved versions of dependencies and their transitive dependencies, so a build with the same inputs resolves the same module versions.
For supply chain work, that has a second benefit: the lock file is a reviewable record. A version change shows up in a pull request diff rather than silently arriving on a Tuesday build.
How to enable it
Locking is enabled per configuration, or for all of them in one line.
dependencyLocking {
lockAllConfigurations()
}
Then generate the lock state by running a task that resolves the configurations with the write-locks argument, for example the dependencies task. In a multi-project build the documentation notes that dependencies runs on one project, typically the root, so plan for that.
./gradlew dependencies --write-locks
Commit the lock files. After that, a build that would resolve a different version fails until you update the lock on purpose.
Do not forget the build script classpath
The documentation is explicit that locking all configurations does not lock the buildscript ones. Plugins are code that runs on your build machines, so lock them too:
buildscript {
configurations.classpath {
resolutionStrategy.activateDependencyLocking()
}
}
Lock mode and selective updates
Gradle offers lock modes. STRICT, set through the lockMode property, makes missing or mismatched lock state fail the build. You can also update specific modules instead of everything, using the update-locks flag with a module name, which keeps upgrades small and reviewable.
Locking versus verification
| Locking | Verification | |
|---|---|---|
| Pins | Resolved versions | Artifact checksums and signatures |
| Catches | Surprise version changes | Tampered or swapped files |
| File | Lock files per configuration | gradle/verification-metadata.xml |
| Works with SNAPSHOT | Not recommended | Not meaningful for changing content |
They do different jobs, and teams that care about repeatable, trustworthy builds use both. See our guide to turning on Gradle dependency verification.
Gradle warns against combining locking with changing versions such as SNAPSHOT, because the coordinates stay the same while content changes. Locking will not give you what you expect there.
When you can skip it
If every dependency already uses exact versions through a platform or version catalog, locking adds less. It still helps with transitive dependencies you did not pin, so many teams enable it anyway.
Try it yourself
Click through it at your own pace, or open it full screen. Watch how a locked build still needs ongoing monitoring, because a pinned version can become vulnerable after the lock was written.
That last point matters. A lock freezes a version, not its safety. Safeguard can rescan your dependencies continuously and open fix pull requests when a pinned version gets an advisory, with remediation off by default until you enable it.
Quick check
Does a lock file stop a malicious package from being used?
Not by itself. It stops version drift. A swapped file at the same version needs checksum or signature verification to be caught.
Should I lock plugins as well?
Yes. By default the buildscript classpath is not locked, and plugins run code during your build.
Sources
Last reviewed: 19 October 2026.