rust-lang/cargo · error

cannot specify a git URL (`{url}`) with a version (`{v}`).

Error message

cannot specify a git URL (`{url}`) with a version (`{v}`).

What it means

`cargo add` does not allow combining a git source with an inline version requirement. The crate specifier (e.g. `docopt@0.8`) cannot carry a version when `--git <url>` is also given, because for a git source the version is determined by the repository checkout, not by a registry version requirement. The bail fires at mod.rs:371 when `crate_spec.version_req()` is `Some` while `arg.git` is set.

Source

Thrown at src/ops/cargo_add/mod.rs:371

        .as_deref()
        .map(CrateSpec::resolve)
        .transpose()?;
    let mut selected_dep = if let Some(url) = &arg.git {
        let mut src = GitSource::new(url);
        if let Some(branch) = &arg.branch {
            src = src.set_branch(branch);
        }
        if let Some(tag) = &arg.tag {
            src = src.set_tag(tag);
        }
        if let Some(rev) = &arg.rev {
            src = src.set_rev(rev);
        }

        let selected = if let Some(crate_spec) = &crate_spec {
            if let Some(v) = crate_spec.version_req() {
                // crate specifier includes a version (e.g. `docopt@0.8`)
                anyhow::bail!("cannot specify a git URL (`{url}`) with a version (`{v}`).");
            }
            let dependency = crate_spec.to_dependency()?.set_source(src);
            let selected = select_package(&dependency, gctx, registry)?;
            if dependency.name != selected.name {
                gctx.shell().warn(format!(
                    "translating `{}` to `{}`",
                    dependency.name, selected.name,
                ))?;
            }
            selected
        } else {
            let source = crate::sources::GitSource::new(src.source_id()?, gctx)?;
            let packages = source.read_packages()?;
            let package = infer_package_for_git_source(packages, &src)?;
            Dependency::from(package.summary())
        };
        selected
    } else if let Some(raw_path) = &arg.path {

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Remove the `@version` from the crate spec: `cargo add --git <url> <crate>`.
  2. If you need a specific revision, pin with `--rev`, `--tag`, or `--branch` instead of a version: `cargo add --git <url> --tag v1.2 <crate>`.
  3. If you actually need a registry version requirement, drop `--git` entirely and use `cargo add <crate>@<version>`.

Example fix

# before
cargo add --git https://example/repo.git mycrate@1.2

# after
cargo add --git https://example/repo.git --tag v1.2 mycrate
Defensive patterns

Strategy: validation

Validate before calling

// A git source and a version req are mutually exclusive; enforce before building DepOp.
fn build_dep_op(name: &str, git: Option<&str>, ver: Option<&str>) -> Result<DepOp, String> {
    match (git, ver) {
        (Some(_), Some(_)) => Err("cannot combine --git with a version requirement".into()),
        (Some(g), None) => Ok(DepOp { crate_spec: Some(name.into()), git: Some(g.into()), ..Default::default() }),
        (None, Some(v)) => Ok(DepOp { crate_spec: Some(format!("{name}@{v}")), ..Default::default() }),
        (None, None) => Ok(DepOp { crate_spec: Some(name.into()), ..Default::default() }),
    }
}

Prevention

When it happens

Trigger: `cargo add --git https://example/repo.git mycrate@1.2` — the `@1.2` portion becomes a `version_req` and conflicts with the git source. Also reachable via programmatic `DepOp { crate_spec: Some("x@1.0"), git: Some(url), .. }`.

Common situations: Users assuming version pins work with git sources like they do with registry crates, or copy-pasting a registry-style spec next to `--git`.

Related errors


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