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

invalid package name `{}`: it is a reserved Windows filename

Error message

invalid package name `{}`: it is a reserved Windows filename{}

What it means

On Windows (cfg!(windows)), check_name hard-rejects a name that restricted_names::is_windows_reserved matches against reserved DOS device filenames (CON, PRN, NUL, COM1-9, LPT1-9, AUX, and case/extension variants). Creating a directory or files with such a name on Windows would fail or shadow a device, so Cargo refuses. On non-Windows the same condition only produces a warning.

Source

Thrown at src/ops/cargo_new.rs:250

    }
    if name == "test" {
        anyhow::bail!(
            "invalid package name `test`: \
            it conflicts with Rust's built-in test library{}",
            bin_help()
        );
    }
    if ["core", "std", "alloc", "proc_macro", "proc-macro"].contains(&name) {
        shell.warn(format!(
            "package name `{}` may be confused with the package with that name in Rust's standard library\n\
            It is recommended to use a different name to avoid problems.{}",
            name,
            bin_help()
        ))?;
    }
    if restricted_names::is_windows_reserved(name) {
        if cfg!(windows) {
            anyhow::bail!(
                "invalid package name `{}`: it is a reserved Windows filename{}",
                name,
                name_help
            );
        } else {
            shell.warn(format!(
                "package name `{}` is a reserved Windows filename\n\
                This package will not work on Windows platforms.",
                name
            ))?;
        }
    }
    if restricted_names::is_non_ascii_name(name) {
        shell.warn(format!(
            "invalid package name `{}`: contains non-ASCII characters\n\
            Non-ASCII crate names are not supported by Rust.",
            name
        ))?;

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Rename to a non-reserved name (avoid CON, PRN, NUL, AUX, COM1-9, LPT1-9 in any case)
  2. Pass `--name <safe-name>` to override
  3. If you hit it on non-Windows only as a warning, treat it as a portability bug and rename anyway

Example fix

# before
cargo new CON
# after
cargo new console   # or: cargo new CON --name console
Defensive patterns

Strategy: validation

Validate before calling

fn is_windows_reserved(name: &str) -> bool {
    let upper = name.to_uppercase();
    let stem = upper.split('.').next().unwrap_or("");
    matches!(stem.as_bytes(),
        b"CON" | b"PRN" | b"AUX" | b"NUL"
    ) || (stem.starts_with("COM") && (1..=9).contains(&stem[3..].parse::<u32>().unwrap_or(0)))
      || (stem.starts_with("LPT") && (1..=9).contains(&stem[3..].parse::<u32>().unwrap_or(0)))
}

if cfg!(windows) && is_windows_reserved(name) { /* reject */ }

Type guard

const WIN_RESERVED = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$/i;
function isWindowsSafe(name: string): boolean { return !WIN_RESERVED.test(name); }

Prevention

When it happens

Trigger: `cargo new CON`, `cargo new --name nul`, `cargo new COM1`, or running cargo new inside a folder whose name is a reserved device name, while actually on a Windows host.

Common situations: Cross-platform projects where a Linux developer created a crate named `aux` or `prn` that then breaks a Windows teammate; portmanteau names that happen to equal a device token; legacy short-name conventions.

Related errors


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