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

  1. Locate the offending file named in the error and rename it to remove the special character (replace `:` with `-`, etc.).
  2. If the file is generated, add it to .gitignore / package.exclude so it is never packaged.
  3. 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

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


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