rust-lang/cargo · error · anyhow::Error

cannot {action} the lock file {lockfile_path} because {locke

Error message

cannot {action} the lock file {lockfile_path} because {locked_flag} was passed to prevent this
help: to generate the lock file without accessing the network, remove the {locked_flag} flag and use --offline instead.

What it means

write_pkg_lockfile is about to change Cargo.lock but a locked flag (--locked or --frozen) is active, which forbids any lockfile mutation. It bails at lockfile.rs:64, reporting whether it would have created or updated the file, and hints to drop the flag and use --offline if the concern was network access.

Source

Thrown at src/ops/lockfile.rs:64

    let (orig, mut out, lock_root) = resolve_to_string_orig(ws, resolve);

    // If the lock file contents haven't changed so don't rewrite it. This is
    // helpful on read-only filesystems.
    if let Some(orig) = &orig {
        if are_equal_lockfiles(orig, &out, ws) {
            return Ok(false);
        }
    }

    if let Some(locked_flag) = ws.gctx().locked_flag() {
        let lockfile_path = lock_root.as_path_unlocked().join(LOCKFILE_NAME);
        let action = if lockfile_path.exists() {
            "update"
        } else {
            "create"
        };
        let lockfile_path = lockfile_path.display();
        anyhow::bail!(
            "cannot {action} the lock file {lockfile_path} because {locked_flag} was passed to prevent this\n\
             help: to generate the lock file without accessing the network, \
             remove the {locked_flag} flag and use --offline instead."
        );
    }

    // While we're updating the lock file anyway go ahead and update its
    // encoding to whatever the latest default is. That way we can slowly roll
    // out lock file updates as they're otherwise already updated, and changes
    // which don't touch dependencies won't seemingly spuriously update the lock
    // file.
    let default_version = ResolveVersion::with_rust_version(ws.lowest_rust_version());
    let current_version = resolve.version();
    let next_lockfile_bump = ws.gctx().cli_unstable().next_lockfile_bump;
    tracing::debug!("lockfile - current: {current_version:?}, default: {default_version:?}");

    if current_version < default_version {
        resolve.set_version(default_version);

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Regenerate the lockfile locally without the flag: `cargo generate-lockfile` (or `cargo update`), commit it, then re-run with --locked/--frozen.
  2. If you only want to avoid network use, drop --locked/--frozen and use `--offline` instead.
  3. In CI, run `cargo fetch --locked` first; if that fails, rebuild the lockfile in a prior step.

Example fix

# before
$ cargo build --frozen
error: cannot update the lock file Cargo.lock because --frozen was passed ...

# after - refresh lockfile, commit, then freeze
$ cargo update
$ git add Cargo.lock && git commit -m "refresh lockfile"
$ cargo build --frozen
# or, avoid network without freezing:
$ cargo build --offline
Defensive patterns

Strategy: validation

Validate before calling

# In CI: refresh the lockfile while unfrozen, then verify it freezes:
cargo generate-lockfile
git diff --exit-code Cargo.lock || cargo update
# now safe to use --locked/--frozen downstream:
cargo fetch --locked
cargo build --frozen

Prevention

When it happens

Trigger: Running a build/publish/fetch with `--locked` or `--frozen` when Cargo.lock is missing or out of date relative to Cargo.toml (dependencies changed, versions drifted).

Common situations: CI with `--frozen` after bumping a dependency in Cargo.toml without running `cargo update`; lockfile not committed; different lockfile between teammates.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/a089e7ddd7ccdb85.json. Report an issue: GitHub.