rust-lang/cargo · error · anyhow::Error
cannot package a filename with a special character `{}`: {}
Error message
cannot package a filename with a special character `{}`: {} What it means
Cargo's packaging step (cargo package / cargo publish) runs check_filename over every file that would go into the .crate archive. It rejects any filename containing one of the Windows-illegal characters `/ \ < > : " | ? *` because such an archive would fail to unpack on Windows. This is a cross-platform safety guard, not a Unix legality check.
Source
Thrown at src/ops/cargo_package/mod.rs:1105
// 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()
))?;
}
Ok(())
}
/// Manages a temporary local registry that we use to overlay our new packages on the
/// upstream registry. This way we can build lockfiles that depend on the new packages even
/// before they're published.View on GitHub (pinned to 0e07a15537)
Solutions
- Locate the offending file named in the error and rename it to remove the special character (replace `:` with `-`, etc.).
- If the file is generated, add it to .gitignore / package.exclude so it is never packaged.
- Regenerate the asset with a Windows-safe naming scheme and re-run `cargo package`.
Example fix
// before: generated file written as // src/assets/log:2024-06-01.txt // // after (generator writes Windows-safe name): // src/assets/log-2024-06-01.txt // and in Cargo.toml: // [package] // exclude = ["src/assets/raw/*"]
Defensive patterns
Strategy: validation
Validate before calling
# Before packaging, scan for Windows-illegal filename characters:
bad='/ \ < > : " | ? *'
find src -type f -print0 | while IFS= read -r -d '' f; do
base="$(basename "$f")"
case "$base" in
*[/'\\'<>":|?*]*) echo "BAD: $f";;
esac
done
# exit non-zero if any BAD lines before running cargo package Prevention
- Configure code generators to emit Windows-safe filenames (no colons, asterisks, question marks).
- Add generated asset directories to package.exclude or .gitignore.
- Run `cargo package --list` first and eyeball the file list for odd names.
When it happens
Trigger: Running `cargo package` or `cargo publish` when the source tree contains a file whose name includes a reserved character (e.g. a generated asset named `report:2024.txt`, a file with `?`, or a stray `*`). The check runs in check_filename at src/ops/cargo_package/mod.rs:1105.
Common situations: Build/code generators that emit files with timestamps containing colons; files committed on Linux that happen to contain `:` or `*`; downstream tooling writing into the package source dir.
Related errors
- {} files in the working directory contain changes that were
- Source directory was modified by build.rs during cargo publi
- found a virtual manifest at `{}` instead of a package manife
- all dependencies must have a version requirement specified w
- cannot specify both `@{v}` and `--version`
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/796241603d5ef5c3.json.
Report an issue: GitHub.