Failed to select a version for ***

I have read through the cargo book and seen other questions of this sort, but do not feel as though I understand how exactly to mitigate and solve this. Could someone help explain how to interpret this error message so that I understand the solution better.

[ERROR rust_analyzer::main_loop] FetchWorkspaceError:
rust-analyzer failed to load workspace: Failed to read Cargo metadata from Cargo.toml file c:\Nothing_to_See_Here\The_One_Project_to_Rule_Them_All\Code\net_test\Cargo.toml, Some(Version { major: 1, minor: 68, patch: 0 }): Failed to run `"cargo" "metadata" "--format-version" "1" "--manifest-path" "c:\\Nothing_to_See_Here\\The_One_Project_to_Rule_Them_All\\Code\\net_test\\Cargo.toml" "--filter-platform" "x86_64-pc-windows-msvc"`: `cargo metadata` exited with an error: error: failed to select a version for `signature`.
    ... required by package `ecdsa v0.14.4`
    ... which satisfies dependency `ecdsa-core = "^0.14"` of package `p256 v0.11.1`
    ... which satisfies dependency `p256 = "^0.11.1"` of package `webrtc-dtls v0.7.0`
    ... which satisfies dependency `dtls = "^0.7.0"` of package `webrtc v0.6.0`
    ... which satisfies dependency `webrtc = "^0.6.0"` of package `libp2p-webrtc v0.4.0-alpha.3`
    ... which satisfies dependency `libp2p-webrtc = "^0.4.0-alpha.3"` of package `libp2p v0.51.1`
    ... which satisfies dependency `libp2p = "^0.51.0"` (locked to 0.51.1) of package `net_test v0.1.0 (C:\Nothing_to_See_Here\The_One_Project_to_Rule_Them_All\Code\net_test)`
versions that meet the requirements `>=1.5, <1.7` are: 1.6.4, 1.6.3, 1.6.2, 1.5.0

all possible versions conflict with previously selected packages.

  previously selected package `signature v1.4.0`
    ... which satisfies dependency `signature = ">=1.3.1, <1.5"` (locked to 1.4.0) of package `ecdsa v0.13.4`
    ... which satisfies dependency `ecdsa-core = "^0.13"` (locked to 0.13.4) of package `p256 v0.10.1`
    ... which satisfies dependency `p256 = "^0.10.0"` (locked to 0.10.1) of package `libp2p-core v0.31.1`
    ... which satisfies dependency `libp2p-core = "^0.31.0"` (locked to 0.31.1) of package `libp2p-episub v0.1.13`
    ... which satisfies dependency `libp2p-episub = "^0.1.13"` (locked to 0.1.13) of package `net_test v0.1.0 (C:\Nothing_to_See_Here\The_One_Project_to_Rule_Them_All\Code\net_test)`

failed to select a version for `signature` which could resolve this conflict

Cargo.toml file

[dependencies]
    async-trait = "0.1.66"
    env_logger = "0.10.0"
    libp2p = { version = "0.51.0", features = ["full"] }
    libp2p-episub = "0.1.13"
    libp2p-identify = "0.42.0"
    local-ip-address = "0.5.1"
    rand = "0.8.5"
    tokio = { version = "1.26.0", features = ["full"] }
    tokio-stream = "0.1.12"
    tokio-util = "0.7.7"
    void = "1.0.2"

These two look incompatible with each other, because libp2p-episub has ecdsa set to version 0.13.* and libp2p has ecdsa set to 0.14.* in their respective dependency trees. Both versions of ecdsa pin the signature crate to specific, incompatible 1.* versions, the former to >= 1.3.1, < 1.5, the latter to >= 1.5, < 1.7. Cargo can't select a version of signature that satisfies both restrictions, hence the resolve error.

Your best bet is to use a lower version of libp2p to fix the error, I'd say. Or open an issue with the libp2p people, asking them to update libp2p-core to use p256 ^0.11.1 instead of ^0.10.0, release a new version and update libp2p-episup to use the new version of libp2p-core.

1 Like

Not OP, but I was under the impression that cargo considers signature 1.4 and signature 1.6 different crates and would compile both and link them to the different ecdsa versions. This avoid the dependency hell that Java and Python have. Is this wrong?

Cargo compiles different versions of the same crate but only between incompatible versions, see the cargo book:

Multiple versions within the same compatibility range are not allowed and will result in a resolver error if it is constrained to two different versions within a compatibility range.

1.4 and 1.6 are in the same compatibility range, i.e. major version of 1.

2 Likes

Also libp2p has a security vulnerability that effects all versions prior to 0.45.1, so you might want to reconsider the dependencies. See RUSTSEC-2022-0084: libp2p: libp2p Lack of resource management DoS › RustSec Advisory Database

1 Like

Cargo is just so finnicky. Originally when I just removed libp2p-episub the error would persist. although the final line of each error statement block was libp2p. Is this because adding libp2p-episub selected package signature v1.4.* and didn't change it when removing libp2p-episub?
Found this thread while looking into it more and was further confused. I fixed the error w/ cargo add libp2p-core (and no libp2p-episub), which by my previous assumption then forcefully updated p256 to v0.11.*
What confused me was, is libp2p-core not a sub-library of libp2p and as such when updating libp2p it would automatically update libp2p-core? (this has also confused me about the need for libp2p features = full and still needing to include libp2p-identify and same with the tokio dependencies)

Post this part I tried adding libp2p-episub again and the original error occurred, although now I know that p256 is the correct version. You then mentioned updating libp2p-episub to use the new version of libp2p-core, but how would I do this?

If you encounter this after removing a dependency, run cargo clean to remove your Cargo.lock and target directory, removing any residual effects from previous compilations.

Actually it is, see this line:

This is not how the resolver works. Adding libp2p-episup still causes the incompatibility between versions, because p256 = ^0.10.0 is incompatible with p256 = ^0.11.1. So cargo will install both versions of p256, which causes the downstream incompatibility of signature = 1.

As far as I know you have two options.

  1. Go to the libp2p-episup repo and tell them about your incompatibility issue, ask them to update the version of libp2p-core they are using and release a new version of their crate. Hopefully that will align their crate with the version of libp2p you are trying to use.

  2. You can override the libp2p-episup dependency with a [patch]. You could clone the libp2p-episup repo to your computer, update the libp2p-core dependency yourself and create an entry like this in your Cargo.toml:

    [patch.crates-io]
    libp2p-episup = { path = "../path/to/libp2p-episup" }
    

I read the issue you linked and this message tells you which version of libp2p-core fixes the incompatibility, namely libp2p-core = ^0.35.1. libp2p-episup (not maintained by the libp2p people by the way) depends on an older, incompatible version of libp2p-core, namely 0.32.0:

If you try and patch this line (hopefully without breaking the libp2p-episup crate) to ^0.35.1 (or even better to the latest version of libp2p-core = 0.39.1), your incompatibility should be resolved.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.