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
- Ensure any crate names / paths you pass to Cargo are valid UTF-8 (they must be for crates.io anyway).
- 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
- Restrict crate names / index paths to ASCII (crates.io already enforces this).
- Never construct non-UTF-8 paths when driving Cargo internals.
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
- config.json not found
- sparse registry url must end in a slash `/`: {url}
- registry said cache valid when no cache exists
- expected rustc or `@path` as first argument
- expected rustc as first argument
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/ac6c35ce6e271471.json.
Report an issue: GitHub.