Poetry lockfile mechanics: pins, hashes, and the --no-update flag
Poetry's lockfile pins exact package versions and hashes for reproducible installs. Learn when to use poetry lock --no-update and how to verify your dependency tree.
11 Aug 2026, 21:00 UTC

Why your Poetry lockfile keeps drifting
When a team runs poetry install on different machines, the dependency tree can subtly shift. A package version that resolves on macOS may pull a different build on Linux, or a developer's local pyproject.toml tweak can leave the lockfile out of sync. The result is inconsistent pip behaviour and mysterious test failures.
Lockfile anatomy: versions, hashes, and groups
Poetry's poetry.lock file does more than record version numbers. For each direct and transitive dependency it stores the exact version alongside a package hash that reflects the downloaded file's content. Because the hash is tied to the specific distribution file, two installs that download the same version from identical indices will produce identical dependency trees, even if the underlying pip behaviour differs across operating systems.
Environment-specific groups such as [dev], [test], and main dependencies are resolved separately. Poetry can generate a consolidated lockfile that includes all groups, or a minimal lockfile for the default group only. Understanding how groups interact prevents optional dependencies from appearing missing when a CI environment activates only the default group.
The poetry lock workflow and --no-update
poetry lock --no-updateThe command poetry lock reads pyproject.toml constraints, resolves the full dependency graph, writes version pins and hashes to poetry.lock, and validates that every package can be fetched from the configured indices. If you only want to refresh the lockfile without bumping any locked versions, use poetry lock --no-update. This flag tells Poetry to keep existing pins intact and only rewrite the lockfile if the underlying constraints in pyproject.toml have changed.
Worked example: fixing a stale lockfile after a constraint change
- Edit the version or constraint for a package in
pyproject.toml, for example raising the maximum version forrequests. - Run
poetry lockto recompute the dependency graph and updatepoetry.lockwith new version pins and hashes. - Verify the change with
poetry show package-name. The output should display the newly locked version and its source hash, matching the entry inpoetry.lock.
If you only intended to update development-only dependencies, you can run poetry lock --no-update after adjusting the [dev] section. This preserves the production pins while refreshing the dev-group lock entries.
Trade-off: when hashes don't match
Hash-based locking depends on the package index state at resolution time. If an index removes a distribution, or if a package author uploads a new build with the same version but different content, the stored hash may no longer be fetchable. In such cases, poetry install will fail with a hash mismatch, and you'll need to either pin an older version or re-resolve from the current index.
Another common pitfall: optional dependencies excluded from the default group may not be installed when poetry install runs in an environment that doesn't explicitly activate their extras. Adding the extra via poetry install --extras extra-name or including it in the default group resolves the gap.
To check that your lockfile is consistent across a team, run the following on each developer's machine and compare the output:
poetry lock && poetry install
poetry show package-nameIf the installed version and its hash match the lockfile entry, the dependency tree is reproducible.
By treating the lockfile as the source of truth for resolved dependencies and using poetry lock --no-update judiciously, teams can avoid accidental version bumps while still keeping constraints current.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.