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
- Rename the offending file to a valid UTF-8 name: `mv` the file (use shell globbing or a tool that handles raw bytes)
- Exclude the file from packaging (move it out of the package source tree or out of any included directory)
- 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
- Restrict repo filenames to UTF-8; add a pre-commit hook to detect non-ASCII names
- Run `cargo package --list` and inspect for mojibake before publishing
- Configure editors/OS locale to UTF-8 to avoid creating codepage-named files
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
- {}This may cause issue during packaging, as modules resoluti
- `{}` resolved to non-UTF value (`{}`)
- everything was utf8
- utf-8 home
- path at `{}` was not valid utf-8
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/1c13e9bfe9724a93.json.
Report an issue: GitHub.