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

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

Error message

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

What it means

check_filename runs on every archived file during `cargo package`. If a source file's filename cannot be converted to a Unicode &str (file.file_name().to_str() returns None), Cargo bails because the resulting .crate would contain a filename that cannot be unpacked on platforms/zip implementations that expect Unicode names. This catches non-UTF-8 OsString filenames (common on Unix where OsString is arbitrary bytes).

Source

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

        .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 0e07a15537)

Solutions

  1. Rename the offending file to a valid UTF-8 name: `mv` the file (use shell globbing or a tool that handles raw bytes)
  2. Exclude the file from packaging (move it out of the package source tree or out of any included directory)
  3. Find it with: `find . -print0 | LC_ALL=C tr -d '\000-\176' >/dev/null` style scans for non-ASCII names

Example fix

# before: src/assets has a non-UTF-8 filename -> cargo package fails
# after: rename using a tool that handles raw bytes
find src/assets -print0 | while IFS= read -r -d '' f; do
  new=$(printf '%s' "$f" | iconv -f UTF-8 -t UTF-8//IGNORE)
  [ "$f" != "$new" ] && mv "$f" "$new"
done
cargo package
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

import { walkSync } from 'fs';
const ASCII = /^[\x20-\x7e]+$/;
function allFilenamesUnicode(root: string): boolean {
  for (const f of walkSync(root)) { if (!ASCII.test(f.path.split('/').pop()!)) return false; }
  return true;
}

Prevention

When it happens

Trigger: `cargo package` in a source tree containing a file whose name includes non-UTF-8 byte sequences (e.g. a Latin-1 or Shift-JIS named file created by an older tool, or a file with a stray byte). check_filename at cargo_package/mod.rs:1096 returns None for to_str().

Common situations: Repos with legacy filenames from Windows or macOS codepages; files dropped in by external tools (screenshot captures with non-ASCII names); assets/ directory containing binary-named resources included via include_dir or similar; cross-platform checkouts where a teammate's locale created an odd filename.

Related errors


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