rust-lang/cargo · error

path does not have a unicode filename which may not unpack…

Error message

path does not have a unicode filename which may not unpack on all platforms: {}

What it means

Thrown by `check_filename` during `cargo package` when a file in the source tree has a filename that cannot be converted to a Unicode string (`to_str()` returns `None`). Such files may fail to unpack on other platforms. This is a cross-platform portability guard.

Solutions

  1. Rename the file to use only valid UTF-8 characters.
  2. Remove the file from the package source tree if it is not needed.
  3. Add it to `.cargoignore` or exclude it via the `exclude` key in Cargo.toml.

Example fix

# Rename on Unix
mv "$(printf 'bad\xffname.txt')" goodname.txt
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn check_all_filenames_unicode(root: &Path) -> Result<(), String> {
    for entry in walkdir::WalkDir::new(root) {
        let entry = entry.map_err(|e| e.to_string())?;
        if entry.file_name().to_str().is_none() {
            return Err(format!("non-unicode filename: {}", entry.path().display()));
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Running `cargo package` on a workspace containing a file whose name includes bytes that are not valid UTF-8 (possible on Unix where filenames are byte strings). The `file.file_name()` succeeds but `.to_str()` returns `None`.

Common situations: Files created by other tools or filesystems that use non-UTF-8 byte sequences in names; files carried over from legacy systems; git checkouts on Unix that preserved non-UTF-8 names.

Related errors


AI-assisted analysis of rust-lang/cargo@495c385d08 (2026-08-11). Data as JSON: /api/errors/1c13e9bfe9724a93. Report an issue: GitHub.

Appendix: source

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

        .collect::<FuturesUnordered<_>>();
    crate::util::block_on(async {
        while futures.try_next().await?.is_some() {}
        CargoResult::Ok(())
    })
}

// It can often be the case that files of a particular name on one platform
// can't actually be created on another platform. For example files with colons
// in the name are allowed on Unix but not on Windows.
//
// To help out in situations like this, issue about weird filenames when
// packaging as a "heads up" that something may not work on other platforms.
fn check_filename(file: &Path, shell: &mut Shell) -> CargoResult<()> {
    let Some(name) = file.file_name() else {
        return Ok(());
    };
    let Some(name) = name.to_str() else {
        anyhow::bail!(
            "path does not have a unicode filename which may not unpack \
             on all platforms: {}",
            file.display()
        )
    };
    let bad_chars = ['/', '\\', '<', '>', ':', '"', '|', '?', '*'];
    if let Some(c) = bad_chars.iter().find(|c| name.contains(**c)) {
        anyhow::bail!(
            "cannot package a filename with a special character `{}`: {}",
            c,
            file.display()
        )
    }
    if restricted_names::is_windows_reserved_path(file) {
        shell.warn(format!(
            "file {} is a reserved Windows filename, \
                it will not work on Windows platforms",
            file.display()

View on GitHub (pinned to 495c385d08)