rust-lang/cargo · error

path at ` ` was not valid utf-8

Error message

path at `{}` was not valid utf-8

What it means

paths::read reads a file as bytes then attempts UTF-8 conversion. If the byte content is not valid UTF-8, it bails with 'path at ... was not valid utf-8'. This is a stricter wrapper over std::fs::read_to_string that yields a clearer, path-annotated error.

Solutions

  1. Re-save the file as UTF-8 (remove BOM for UTF-16; convert encoding).
  2. If binary is expected, use paths::read_bytes instead of paths::read.
  3. Validate encoding before reading (e.g. check for a BOM or run a UTF-8 validity check).
  4. Fix the upstream producer to emit UTF-8.

Example fix

// before
let s = paths::read(&path)?;  // panics-style bail on non-utf8
// after
let bytes = paths::read_bytes(&path)?;
let s = String::from_utf8_lossy(&bytes).into_owned();
Defensive patterns

Strategy: validation

Validate before calling

// Check UTF-8 validity before calling paths::read
let bytes = std::fs::read(&path)?;
if std::str::from_utf8(&bytes).is_err() {
    eprintln!("{} is not valid UTF-8", path.display());
}
// or just use paths::read_bytes when encoding is unknown

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Calling paths::read on a file whose bytes are not valid UTF-8: binary files, files in Latin-1/GBK/UTF-16/Shift-JIS encodings, or files with stray invalid byte sequences.

Common situations: Reading a config/lock/manifest that was saved in a non-UTF-8 encoding (notably UTF-16 BOM on Windows editors); accidentally reading a binary artifact; corrupted file with truncated multi-byte sequences.

Related errors


AI-assisted analysis of rust-lang/cargo@42eee92bc9 (2026-08-11). Data as JSON: /api/errors/307b2c7fb5db7da2. Report an issue: GitHub.

Appendix: source

Thrown at crates/cargo-util/src/paths.rs:172

        .with_context(|| format!("failed to load metadata for path `{}`", path.display()))
}

/// Returns metadata for a file without following symlinks.
///
/// Equivalent to [`std::fs::metadata`] with better error messages.
pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> Result<Metadata> {
    let path = path.as_ref();
    std::fs::symlink_metadata(path)
        .with_context(|| format!("failed to load metadata for path `{}`", path.display()))
}

/// Reads a file to a string.
///
/// Equivalent to [`std::fs::read_to_string`] with better error messages.
pub fn read(path: &Path) -> Result<String> {
    match String::from_utf8(read_bytes(path)?) {
        Ok(s) => Ok(s),
        Err(_) => anyhow::bail!("path at `{}` was not valid utf-8", path.display()),
    }
}

/// Reads a file into a bytes vector.
///
/// Equivalent to [`std::fs::read`] with better error messages.
pub fn read_bytes(path: &Path) -> Result<Vec<u8>> {
    fs::read(path).with_context(|| format!("failed to read `{}`", path.display()))
}

/// Writes a file to disk.
///
/// Equivalent to [`std::fs::write`] with better error messages.
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> Result<()> {
    let path = path.as_ref();
    fs::write(path, contents.as_ref())
        .with_context(|| format!("failed to write `{}`", path.display()))
}

View on GitHub (pinned to 42eee92bc9)