Lock File: install, update & sync

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the Python Reference bibliography.

poetry.lock is the part of a Poetry project that makes installs reproducible. This page describes its format and the four commands that read or write it, lock, install, update and sync, for Poetry 2.5.1. The examples ran on CPython 3.14.6 on 2026-10-22 on copies of the Poetry flavour of birdtally; hashes in quoted TOML strings are shortened with …. The comparison with pip’s lock formats is on Lock Files & Reproducible Installs.

stateDiagram-v2 direction LR state "pyproject.toml" as P state "poetry.lock" as L state "environment (.venv)" as E P --> L: poetry lock (keeps locked versions) P --> L: poetry lock --regenerate, poetry update (newest allowed) L --> E: poetry install (adds and updates, removes nothing extra) L --> E: poetry sync (and removes what is not selected) P --> E: poetry add / remove (lock, then install)

The format

# This file is automatically @generated by Poetry 2.5.1 and should not be changed by hand.

[[package]]
name = "click"
version = "8.5.0"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.10"
groups = ["docs"]
files = [
    {file = "click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360"},
    {file = "click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34"},
]
…

[metadata]
lock-version = "2.1"
python-versions = ">=3.10"
content-hash = "e6de9ee1…c8d825f4"
  • The header names the Poetry version that wrote the file and the rule: "should not be changed by hand".

  • [[package]] entries list every package for every group, extra and platform, with the hashes of all files of the version (here the wheel and the sdist), so the same lock installs anywhere.

  • groups and markers per package are new in lock-version = "2.1" (Poetry 2.0). With them the installer can decide what to install by evaluating markers instead of resolving again (installer.re-resolve = false, below).

  • [metadata] content-hash is the SHA-256 of the parts of pyproject.toml that affect resolution. In Poetry 2.5.1’s locker.py these are requires-python, dependencies and optional-dependencies of [project], the whole [dependency-groups] table, and dependencies, source, extras, dev-dependencies and group of [tool.poetry]. Editing a description or a version number does not make the lock stale; editing a dependency does.

  • Poetry 2.5.1 reads lock versions 1.x and 2.x and writes 2.1.

Since Poetry 2.3 the PEP 735 [dependency-groups] table is part of the hash. A lock written by 2.3 or later therefore looks outdated to Poetry 2.2.x for a project that uses PEP 735 groups, and the other way round; pin the Poetry version of a team with requires-poetry = ">=2.3".

poetry lock

poetry lock resolves and writes the lock without installing anything. Since Poetry 2.0 it keeps the versions that are already locked and changes only what pyproject.toml requires (the old --no-update behaviour is now the default and the option was removed). --regenerate ignores the existing lock and resolves from scratch, which normally gives the same result as poetry update --lock.

A lock made with a 200-day cooldown pinned ruff 0.15.9. A plain poetry lock kept it; updating one package moved it:

POETRY_SOLVER_MIN_RELEASE_AGE=200 poetry lock --regenerate
grep -A1 'name = "ruff"' poetry.lock
poetry lock
grep -A1 'name = "ruff"' poetry.lock
poetry update ruff --lock
grep -A1 'name = "ruff"' poetry.lock
Writing lock file
name = "ruff"
version = "0.15.9"
Resolving dependencies...
name = "ruff"
version = "0.15.9"
Writing lock file
name = "ruff"
version = "0.17.1"

A stale lock

When the relevant parts of pyproject.toml change, the lock no longer matches. Changing the pretty extra from rich>=13 to rich>=14:

poetry install
poetry check --lock
Installing dependencies from lock file

pyproject.toml changed significantly since poetry.lock was last generated. Run `poetry lock` to fix the lock file.
Error: pyproject.toml changed significantly since poetry.lock was last generated. Run `poetry lock` to fix the lock file.

Both commands exit with 1, and nothing is installed (since Poetry 1.8 an inconsistent lock is an error, not a warning). poetry check --lock (1.6, replacing lock --check) is the check to run in CI; after poetry lock it prints All set!.

An incompatible lock

A lock written by a newer Poetry with a newer major lock version cannot be read. With lock-version = "3.0" edited in:

Installing dependencies from lock file

The lock file is not compatible with the current version of Poetry.
Upgrade Poetry to be able to read the lock file or, alternatively, regenerate the lock file with the `poetry lock` command.

Upgrade Poetry, as the message says, rather than regenerating and losing the pinned versions.

Merge conflicts

Two branches that each change dependencies conflict in poetry.lock, and the conflicted file is invalid TOML whose content-hash matches neither side. Never merge it by hand: resolve the conflict in pyproject.toml, then take either side of the lock (for example git checkout --theirs poetry.lock) and run poetry lock, which re-resolves only what changed.

install, update and sync

Command Reads the lock? Changes the lock?

poetry install

Yes; installs exactly what it lists for the selected groups and extras. Resolves only when there is no lock.

Only when there was none.

poetry update [pkg…]

No; re-resolves the named packages (or everything) to the newest allowed versions.

Yes, then installs.

poetry sync

Yes, like install, and also removes packages that are not part of the selection.

Only when there was none.

poetry lock

Keeps locked versions.

Yes; installs nothing.

The Poetry documentation recommends poetry sync over poetry install for reproducible environments, because install never removes anything, so packages you dropped from pyproject.toml (or installed by hand) stay. The exception is virtualenvs.create = false or virtualenvs.options.system-site-packages = true: sync would then try to remove packages that do not belong to the project, so use install there.

Options

Option install sync Meaning

--with, --without, --only

✓

✓

Group selection (--without wins over --with); see Installing groups.

--all-groups

✓

✓

All groups, optional ones included.

-E, --extras, --all-extras

✓

✓

Extras of the project. sync removes extras that are not selected.

--no-root

✓

✓

Do not install the project itself.

--only-root

✓

✓

Only the project, no dependencies.

--no-directory

✓

✓

Skip directory path dependencies (for Docker layers).

--compile

✓

✓

Byte-compile the installed files.

--dry-run

✓

✓

Print the operations (implies -v).

--sync

deprecated

Use poetry sync (2.0).

poetry update accepts --with, --without and --only (they choose what gets installed; the lock is always resolved for all groups), --dry-run, --lock (update the lock, do not install) and --sync. The update --help text in 2.5.1 lists --sync without the "(Deprecated)" label that install --sync carries, although the replacement is the same poetry sync.

Since Poetry 2.4, naming a package that is not a dependency is an error:

poetry update nosuchpkg
The following packages are not dependencies of this project: nosuchpkg

poetry update rich updates rich within its constraint; it does nothing if the newest allowed version is already locked. To go past the constraint use poetry add rich@latest.

installer.re-resolve

With a 2.1 lock the installer can either re-resolve the locked packages for the target environment (the 1.x behaviour) or simply evaluate the locked markers. installer.re-resolve (POETRY_INSTALLER_RE_RESOLVE) chooses; it was introduced in 2.0 with true as the default and defaults to false since 2.3. false is faster and is required for the exclusive-extras pattern on Dependency Specification.

Cooldowns

solver.min-release-age (Poetry 2.4) makes lock, add and update ignore releases younger than a number of days; the lock above was made that way. The settings and their pitfalls are on Supply-Chain Security.

pip and Poetry

Poetry pip

poetry lock

pip lock (experimental, one platform), or a hashed requirements file

poetry install

pip install -r requirements.lock / pip install -r pylock.toml

poetry sync

A fresh venv plus the above; pip never removes unlisted packages

poetry update rich

pip install -U rich, then re-lock

poetry check --lock

No equivalent; compare the lock you generate in CI with the committed one