rust-lang/cargo · error
invalid package name
Error message
invalid package name `{}`: it is a Rust keyword{} What it means
`restricted_names::is_keyword` returns true for any of Rust's reserved keywords (`fn`, `crate`, `impl`, `match`, `async`, etc.). Cargo forbids these as package names because they collide with the language grammar and would break `use`/`extern crate` references. The bail appends `bin_help()` showing how to keep a binary by that logical name via `[[bin]]`.
Solutions
- Pick a non-keyword name: suffix/prefix it, e.g. `match-tool`, `my_async`, `learn-trait`.
- Keep the binary's logical name but use a valid package name plus `[[bin]] name = "match"` in Cargo.toml (as the help text shows), or place it at `src/bin/match.rs`.
- Consult the keyword list (https://doc.rust-lang.org/reference/keywords.html) when choosing names.
Example fix
# before $ cargo new match # error: Rust keyword # after $ cargo new match-tool # Cargo.toml — keep binary named "match" if desired: # [[bin]] # name = "match" # path = "src/main.rs"
Defensive patterns
Strategy: validation
Validate before calling
const KEYWORDS: &[&str] = &["Self","abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"];
fn is_keyword(name: &str) -> bool { KEYWORDS.contains(&name) } Type guard
fn is_non_keyword_name(name: &str) -> bool { !is_keyword(name) } Prevention
- Check the chosen name against Rust's keyword list before creating.
- Suffix/prefix concept names that collide (e.g. `match-tool`).
- In generators, keep a deny-list of keywords and reject or auto-rename.
- Cross-reference https://doc.rust-lang.org/reference/keywords.html.
When it happens
Trigger: `cargo new fn`, `cargo init --name match`, `cargo new --name crate mytool`, or any name matching the keyword list in `restricted_names.rs`.
Common situations: Creating a tutorial/example crate named after a concept (`match`, `async`, `trait`). Auto-generating from a directory literally named `test`-adjacent keywords. Tooling that derives crate names from filenames matching keywords.
Related errors
- {err}{help}
- invalid package name
- invalid package name `test`: it conflicts with Rust's…
- invalid package name
- can't specify both lib and binary outputs
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/8ed455a1939b8af1.
Report an issue: GitHub.
Appendix: source
Thrown at src/ops/cargo_new.rs:159
This can be done by setting the binary filename to `src/bin/{name}.rs` \
or change the name in Cargo.toml with:\n\
\n \
[[bin]]\n \
name = \"{name}\"\n \
path = \"src/main.rs\"\n\
",
name = name
));
}
help
};
PackageName::new(name).map_err(|err| {
let help = bin_help();
anyhow::anyhow!("{err}{help}")
})?;
if restricted_names::is_keyword(name) {
anyhow::bail!(
"invalid package name `{}`: it is a Rust keyword{}",
name,
bin_help()
);
}
if restricted_names::is_conflicting_artifact_name(name) {
if has_bin {
anyhow::bail!(
"invalid package name `{}`: \
it conflicts with cargo's build directory names{}",
name,
name_help
);
} else {
shell.warn(format!(
"package `{}` will not support binary \
executables with that name, \
it conflicts with cargo's build directory names",View on GitHub (pinned to 98a09e7e7d)