rust-lang/cargo · error · anyhow::Error

non UTF8 path: {}

Error message

non UTF8 path: {}

What it means

In `HttpRegistry::load` (src/sources/registry/http_remote.rs:281) Cargo converts the OS `Path` for an index entry into a `&str` via `path.to_str()`. On Windows (or any platform whose OS paths can be non-UTF-8) a path containing invalid Unicode yields `None` and this error. The sparse registry builds URLs by string concatenation, so a non-UTF-8 path can't be turned into a fetchable URL.

Source

Thrown at src/sources/registry/http_remote.rs:283

    }

    async fn load(
        &self,
        _root: &Path,
        path: &Path,
        index_version: Option<&str>,
    ) -> CargoResult<LoadResponse> {
        // Ensure the config is loaded.
        let Some(config) = self.config_opt().await? else {
            return Ok(LoadResponse::NotFound);
        };
        self.inner()
            .auth_required
            .update(|v| v || config.auth_required);

        let path = path
            .to_str()
            .ok_or_else(|| anyhow::anyhow!("non UTF8 path: {}", path.display()))?;
        self.sparse_fetch(path, index_version).await
    }

    async fn config(&self) -> CargoResult<Option<RegistryConfig>> {
        Ok(Some(self.config().await?))
    }

    fn invalidate_cache(&self) {
        // Actually updating the index is more or less a no-op for this implementation.
        // All it does is ensure that a subsequent load will double-check files with the
        // server rather than rely on a locally cached copy of the index files.
        debug!("invalidated index cache");
        self.inner().fresh.borrow_mut().clear();
        self.inner().requested_update.set(true);
    }

    fn set_quiet(&mut self, quiet: bool) {
        self.inner().quiet.set(quiet);

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Ensure any crate names / paths you pass to Cargo are valid UTF-8 (they must be for crates.io anyway).
  2. Treat as an internal invariant violation — file a cargo issue with the path bytes if you encounter it.
Defensive patterns

Strategy: validation

Validate before calling

// Before calling sparse load(), assert the path is UTF-8.
fn ensure_utf8_path(path: &Path) -> CargoResult<&str> {
    path.to_str().ok_or_else(|| anyhow::anyhow!("non UTF8 path: {}", path.display()))
}

Type guard

// Narrow a Path to a &str only when it is valid UTF-8.
pub fn utf8_path(p: &Path) -> Option<&str> { p.to_str() }

Prevention

When it happens

Trigger: A crate name or index path containing bytes that aren't valid UTF-8 reaching the sparse `load()` path. Cargo crate names are restricted to ASCII, so this is essentially unreachable through normal crates.io usage; it can only occur from an internally-constructed non-UTF-8 path or a corrupted in-memory state.

Common situations: Effectively never seen for crates.io (names are validated to `[A-Za-z0-9_-]`). Could surface in custom tooling that drives Cargo internals with non-UTF-8 paths, or on Windows with paths produced from non-UTF-16 sources.

Related errors


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