Cargo installs crates and fetches dependencies from a “registry”. The default registry is A registry contains an “index” which contains a searchable list of available crates. A registry may also provide a web API to support publishing new crates directly from Cargo.

Note: If you are interested in mirroring or vendoring an existing registry, take a look at Source Replacement.

If you are implementing a registry server, see Running a Registry for more details about the protocol between Cargo and a registry.

If you’re using a registry that requires authentication, see Registry Authentication. If you are implementing a credential provider, see Credential Provider Protocol for details.

Using an Alternate Registry

To use a registry other than, the name and index URL of the registry must be added to a .cargo/config.toml file. The registries table has a key for each registry, for example:

my-registry = { index = "https://my-intranet:8080/git/index" }

The index key should be a URL to a git repository with the registry’s index or a Cargo sparse registry URL with the sparse+ prefix.

A crate can then depend on a crate from another registry by specifying the registry key and a value of the registry’s name in that dependency’s entry in Cargo.toml:

# Sample Cargo.toml
name = "my-project"
version = "0.1.0"
edition = "2021"

other-crate = { version = "1.0", registry = "my-registry" }

As with most config values, the index may be specified with an environment variable instead of a config file. For example, setting the following environment variable will accomplish the same thing as defining a config file:


Note: does not accept packages that depend on crates from other registries.

Publishing to an Alternate Registry

If the registry supports web API access, then packages can be published directly to the registry from Cargo. Several of Cargo’s commands such as cargo publish take a --registry command-line flag to indicate which registry to use. For example, to publish the package in the current directory:

  1. cargo login --registry=my-registry

    This only needs to be done once. You must enter the secret API token retrieved from the registry’s website. Alternatively the token may be passed directly to the publish command with the --token command-line flag or an environment variable with the name of the registry such as CARGO_REGISTRIES_MY_REGISTRY_TOKEN.

  2. cargo publish --registry=my-registry

Instead of always passing the --registry command-line option, the default registry may be set in .cargo/config.toml with the registry.default key. For example:

default = "my-registry"

Setting the package.publish key in the Cargo.toml manifest restricts which registries the package is allowed to be published to. This is useful to prevent accidentally publishing a closed-source package to The value may be a list of registry names, for example:

# ...
publish = ["my-registry"]

The publish value may also be false to restrict all publishing, which is the same as an empty list.

The authentication information saved by cargo login is stored in the credentials.toml file in the Cargo home directory (default $HOME/.cargo). It has a separate table for each registry, for example:

token = "854DvwSlUwEHtIo3kWy6x7UCPKHfzCmy"

Registry Protocols

Cargo supports two remote registry protocols: git and sparse. If the registry index URL starts with sparse+, Cargo uses the sparse protocol. Otherwise Cargo uses the git protocol.

The git protocol stores index metadata in a git repository and requires Cargo to clone the entire repo.

The sparse protocol fetches individual metadata files using plain HTTP requests. Since Cargo only downloads the metadata for relevant crates, the sparse protocol can save significant time and bandwidth.

The registry supports both protocols. The protocol for is controlled via the registries.crates-io.protocol config key.