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

  1. Verify the registry URL is reachable: `curl -i <registry-index>/config.json`.
  2. Confirm the registry is correctly declared in `.cargo/config.toml` (`registries.<name> = { index = "..." }`).
  3. For private registries, ensure the server actually serves a `config.json` (e.g. ship it via the registry tooling).
  4. 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

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


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