rust-lang/cargo · error
remote registries must have config
Error message
remote registries must have config
What it means
Invariant in registry operations: `block_on(src.config())...expect("remote registries must have config")`. For a remote registry, cargo expects the registry source to always produce a `RegistryConfig` after fetching. The expect fires if `config()` returns `Ok(None)` — the registry provided no config payload.
Source
Thrown at src/ops/registry/mod.rs:147
) -> CargoResult<(Registry<RegistryClient<'gctx>>, RegistrySource<'gctx>)> {
let is_index = reg_or_index.map(|v| v.is_index()).unwrap_or_default();
if is_index && token_required.is_some() && token_from_cmdline.is_none() {
bail!("command-line argument --index requires --token to be specified");
}
if let Some(token) = token_from_cmdline {
auth::cache_token_from_commandline(gctx, &source_ids.original, token);
}
let src = RegistrySource::remote(source_ids.replacement, gctx)?;
let cfg = {
let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
// Only update the index if `force_update` is set.
if force_update {
src.invalidate_cache()
}
crate::util::block_on(src.config())
.with_context(|| format!("failed to update {}", source_ids.replacement))?
.expect("remote registries must have config")
};
let api_host = cfg
.api
.ok_or_else(|| format_err!("{} does not support API commands", source_ids.replacement))?;
let token = if token_required.is_some() || cfg.auth_required {
let operation = token_required.unwrap_or(Operation::Read);
Some(auth::auth_token(
gctx,
&source_ids.original,
None,
operation,
vec![],
false,
)?)
} else {
None
};
let handle = RegistryClient(gctx.http_async()?);View on GitHub (pinned to 0e07a15537)
Solutions
- Verify the registry URL is reachable: `curl -i <registry-index>/config.json`.
- Confirm the registry is correctly declared in `.cargo/config.toml` (`registries.<name> = { index = "..." }`).
- For private registries, ensure the server actually serves a `config.json` (e.g. ship it via the registry tooling).
- Retry after `cargo login` / clearing the index cache (`cargo cache` or removing `~/.cargo/registry/index`).
Defensive patterns
Strategy: validation
Validate before calling
// Before a registry API command, probe config.json existence.
let cfg_url = format!("{}/config.json", registry_index_url.trim_end_matches('/'));
let resp = reqwest::blocking::head(&cfg_url)?;
if !resp.status().is_success() {
return Err(anyhow!("registry {} has no config.json (HTTP {})", registry_index_url, resp.status()));
} Prevention
- Confirm private registries serve `config.json` at the index root.
- Keep `.cargo/config.toml` registry `index` URLs correct (sparse vs git).
- Re-`cargo login` and clear the index cache when registry behavior changes.
When it happens
Trigger: Running a registry-API command (`cargo publish`, `cargo yank`, `cargo owner`, `cargo login`, `cargo search`) against a remote registry whose index returned no config (no `config.json` in the index). Typically indicates an empty/misconfigured private registry or a source-replacement pointing at a non-registry.
Common situations: Private registry not fully initialized (index exists but `config.json` missing); a `sparse+` registry whose host returns 404 for `config.json`; a `[source]` replacement accidentally pointing at a git index when a sparse index is expected; network/proxy returning an empty body that parses as no-config.
Related errors
- already loaded config values
- len() == 1 above
- must be utf-8 in toml
- latest always has a source
- source should be resolved before here
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/10cc32d1fc5c22ed.json.
Report an issue: GitHub.