rust-lang/cargo · error

everything was utf8

Error message

everything was utf8

What it means

`check_for_file_and_add` converts a relative path to a `&str` via `rel_file_path.to_str().expect("everything was utf8")`. On platforms with non-UTF-8 filenames (non-UTF-8 locale, exotic Unicode normalization, or intentionally binary-named files), `Path::to_str` returns `None` and the expect panics during `cargo package`.

Source

Thrown at src/ops/cargo_package/mod.rs:658

    Ok(result)
}

fn check_for_file_and_add(
    label: &str,
    file_path: &Path,
    abs_file_path: PathBuf,
    pkg: &Package,
    result: &mut Vec<ArchiveFile>,
    ws: &Workspace<'_>,
) -> CargoResult<()> {
    match abs_file_path.strip_prefix(&pkg.root()) {
        Ok(rel_file_path) => {
            if !result.iter().any(|ar| ar.rel_path == rel_file_path) {
                result.push(ArchiveFile {
                    rel_path: rel_file_path.to_path_buf(),
                    rel_str: rel_file_path
                        .to_str()
                        .expect("everything was utf8")
                        .to_string(),
                    contents: FileContents::OnDisk(abs_file_path),
                })
            }
        }
        Err(_) => {
            // The file exists somewhere outside of the package.
            let file_name = file_path.file_name().unwrap();
            if result.iter().any(|ar| ar.rel_path == file_name) {
                ws.gctx().shell().warn(&format!(
                    "{} `{}` appears to be a path outside of the package, \
                            but there is already a file named `{}` in the root of the package. \
                            The archived crate will contain the copy in the root of the package. \
                            Update the {} to point to the path relative \
                            to the root of the package to remove this warning.",
                    label,
                    file_path.display(),
                    file_name.to_str().unwrap(),

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Rename the offending file/directory to valid UTF-8 — find it via `find . -print0 | tr '\0' '\n' | grep -axv '.*'` or `locale` checks.
  2. Set a UTF-8 locale in your shell/CI (`export LC_ALL=C.UTF-8 LANG=C.UTF-8`) and retry packaging.
  3. Remove the non-UTF-8 entry from the package via `.gitignore`/`exclude` in `Cargo.toml` if it shouldn't ship.
  4. If the file must be included, report a cargo enhancement request for lossy-path handling in the archive.

Example fix

// before
rel_str: rel_file_path.to_str().expect("everything was utf8").to_string(),

// after (graceful error pointing at the bad path)
rel_str: rel_file_path.to_str()
    .ok_or_else(|| anyhow::format_err!(
        "path `{}` is not valid UTF-8 and cannot be packaged", rel_file_path.display()))?
    .to_string(),
Defensive patterns

Strategy: validation

Validate before calling

// Before packaging, scan for non-UTF-8 paths in the crate tree.
for entry in walkdir::WalkDir::new(".") {
    let p = entry?.into_path();
    if p.to_str().is_none() {
        return Err(anyhow!("non-UTF-8 path cannot be packaged: {}", p.display()));
    }
}

Prevention

When it happens

Trigger: Running `cargo package` when a tracked source file (or a `[[bin]].path`, `[lib].path`, build-script, include, etc.) contains bytes that are not valid UTF-8. Most common on macOS with NFD-normalized names outside the UTF-8 range, or on Linux with byte-sequences invalid in the active locale.

Common situations: Non-UTF-8 file or directory names in the crate source tree; files created by tools that emit raw byte names; packaging a crate checked out on a filesystem that mangles encoding; CI on a host with `LANG=C` handling non-ASCII paths.

Related errors


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