rust-lang/cargo · error
unrecognized feature{} for crate {}: {}
Error message
unrecognized feature{} for crate {}: {} What it means
`cargo add` validates requested feature names against the set of features the chosen crate actually exposes (from its index summary or manifest). If any requested feature (including inherited ones) is not in `dep.available_features`, the operation is aborted. The message lists the unknown features and, when possible, appends edit-distance suggestions and the available enabled/disabled feature sets to help correct the typo.
Source
Thrown at src/ops/cargo_add/mod.rs:239
.map(|s| s.to_string())
.coalesce(|x, y| if x.len() + y.len() < 78 {
Ok(format!("{x}, {y}"))
} else {
Err((x, y))
})
.into_iter()
.format("\n ")
)?;
} else {
writeln!(
message,
"\n\n{} enabled features available",
activated.len()
)?;
}
}
}
anyhow::bail!(message.trim().to_owned());
}
print_dep_table_msg(&mut options.gctx.shell(), &dep)?;
manifest.insert_into_table(
&dep_table,
&dep,
workspace.gctx(),
workspace.root(),
options.spec.manifest().unstable_features(),
)?;
if dep.optional == Some(true) {
let is_namespaced_features_supported =
check_rust_version_for_optional_dependency(options.spec.rust_version())?;
if is_namespaced_features_supported {
let dep_key = dep.toml_key();
if !manifest.is_explicit_dep_activation(dep_key) {
let table = manifestView on GitHub (pinned to 0e07a15537)
Solutions
- Re-read the error's printed feature list and pick the exact spelling it suggests (it includes edit-distance suggestions).
- Check the selected crate version's feature list: `cargo add <crate> --dry-run` or consult `docs.rs/<crate>` for that version.
- Pin to a version known to expose the feature (`cargo add <crate>@<version> --features <name>`) or drop the unknown feature.
Example fix
# before cargo add serde --features derivee # after cargo add serde --features derive
Defensive patterns
Strategy: validation
Validate before calling
// Fetch available features from the registry metadata and diff before invoking add.
// Pseudocode using `crates_io_api` or `cargo metadata`:
fn validate_features(crate_name: &str, version: &str, wanted: &[String]) -> Result<(), Vec<String>> {
let available: Vec<String> = fetch_features(crate_name, version); // your lookup
let unknown: Vec<_> = wanted.iter().filter(|f| !available.contains(f)).cloned().collect();
if unknown.is_empty() { Ok(()) } else { Err(unknown) }
} Prevention
- Consult docs.rs for the exact version you pin before copying a feature list.
- Normalize feature strings (lowercase, hyphen-vs-underscore) before passing them.
- Prefer pinning the crate version (`name@ver`) so the feature set is deterministic.
When it happens
Trigger: Running `cargo add serde --features derivee` (typo) or passing a feature that exists in a different version than the one selected, e.g. `cargo add tokio --features full` against a tokio version that lacks `full`. Both `dep.features` and `dep.inherited_features` are diffed against `available_features` at mod.rs:148-157.
Common situations: Feature renamed or removed between crate versions (e.g. a 0.x crate restructured its features), case mistakes (`--features Default`), hyphen/underscore confusion, or copying a feature list from outdated documentation.
Related errors
- manifest validated
- not implemented
- feature `{feature}` must be qualified by the dependency it's
- feature `{feature}` is not allowed to use explicit `dep:` sy
- `{feature}` is unsupported when inferring the crate name, us
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/4850b3821417a768.json.
Report an issue: GitHub.