{"id":"1c13e9bfe9724a93","repo":"rust-lang/cargo","slug":"path-does-not-have-a-unicode-filename-which-may-no","errorCode":null,"errorMessage":"path does not have a unicode filename which may not unpack on all platforms: {}","messagePattern":"path does not have a unicode filename which may not unpack on all platforms: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/ops/cargo_package/mod.rs","lineNumber":1097,"sourceCode":"        .collect::<FuturesUnordered<_>>();\n    crate::util::block_on(async {\n        while futures.try_next().await?.is_some() {}\n        CargoResult::Ok(())\n    })\n}\n\n// It can often be the case that files of a particular name on one platform\n// can't actually be created on another platform. For example files with colons\n// in the name are allowed on Unix but not on Windows.\n//\n// To help out in situations like this, issue about weird filenames when\n// packaging as a \"heads up\" that something may not work on other platforms.\nfn check_filename(file: &Path, shell: &mut Shell) -> CargoResult<()> {\n    let Some(name) = file.file_name() else {\n        return Ok(());\n    };\n    let Some(name) = name.to_str() else {\n        anyhow::bail!(\n            \"path does not have a unicode filename which may not unpack \\\n             on all platforms: {}\",\n            file.display()\n        )\n    };\n    let bad_chars = ['/', '\\\\', '<', '>', ':', '\"', '|', '?', '*'];\n    if let Some(c) = bad_chars.iter().find(|c| name.contains(**c)) {\n        anyhow::bail!(\n            \"cannot package a filename with a special character `{}`: {}\",\n            c,\n            file.display()\n        )\n    }\n    if restricted_names::is_windows_reserved_path(file) {\n        shell.warn(format!(\n            \"file {} is a reserved Windows filename, \\\n                it will not work on Windows platforms\",\n            file.display()","sourceCodeStart":1079,"sourceCodeEnd":1115,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/ops/cargo_package/mod.rs#L1079-L1115","documentation":"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).","triggerScenarios":"`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().","commonSituations":"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.","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"],"exampleFix":"# before: src/assets has a non-UTF-8 filename -> cargo package fails\n# after: rename using a tool that handles raw bytes\nfind src/assets -print0 | while IFS= read -r -d '' f; do\n  new=$(printf '%s' \"$f\" | iconv -f UTF-8 -t UTF-8//IGNORE)\n  [ \"$f\" != \"$new\" ] && mv \"$f\" \"$new\"\ndone\ncargo package","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn ensure_unicode_filenames(root: &Path) -> Result<(), String> {\n    for entry in walkdir::WalkDir::new(root) {\n        let entry = entry.map_err(|e| e.to_string())?;\n        if entry.file_type().is_file() {\n            if entry.file_name().to_str().is_none() {\n                return Err(format!(\"non-unicode filename: {}\", entry.path().display()));\n            }\n        }\n    }\n    Ok(())\n}","typeGuard":"import { walkSync } from 'fs';\nconst ASCII = /^[\\x20-\\x7e]+$/;\nfunction allFilenamesUnicode(root: string): boolean {\n  for (const f of walkSync(root)) { if (!ASCII.test(f.path.split('/').pop()!)) return false; }\n  return true;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["cargo-package","unicode","filesystem","portability","encoding"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}