rust-lang/cargo · error · anyhow::Error
unrecognized feature
Error message
unrecognized feature{} for crate {}: {} What it means
Thrown by cargo add when the user requests features via --features or -F that do not exist on the target crate. The error message lists the unrecognized feature names, suggests close matches via edit-distance, and shows available features. The bail occurs at line 240 after the full message is assembled.
Solutions
- Check the error message for suggested features via edit-distance matching
- Review the 'available features' list printed in the error output
- Inspect the crate's Cargo.toml or documentation to find valid feature names
- Update the feature name to match an existing one
Example fix
# before cargo add serde --features derrive # error: unrecognized feature `derrive` for crate serde # after — fix typo cargo add serde --features derive
Defensive patterns
Strategy: validation
Validate before calling
// Validate feature names before running cargo add
fn validate_features(crate_name: &str, requested: &[String]) -> Result<(), String> {
// Fetch available features from the crate's metadata
let output = std::process::Command::new("cargo")
.args(["info", crate_name, "--format-version", "1"])
.output().map_err(|e| e.to_string())?;
let metadata: serde_json::Value = serde_json::from_slice(&output.stdout)
.map_err(|e| e.to_string())?;
let available: Vec<&str> = metadata["features"].as_object()
.map(|m| m.keys().map(|s| s.as_str()).collect())
.unwrap_or_default();
for feat in requested {
if !available.contains(&feat.as_str()) {
return Err(format!("unrecognized feature `{feat}` for crate {crate_name}"));
}
}
Ok(())
} Prevention
- Check available features via cargo info <crate> or the crate's documentation before specifying --features
- Watch for edit-distance suggestions in the error output for typo correction
- Be aware that features may change between major versions of a crate
When it happens
Trigger: Running `cargo add foo --features bar` where 'bar' is not a feature defined in crate 'foo'. The unknown_features set is computed by diffing requested features against dep.available_features.
Common situations: Typo in a feature name. The feature was renamed or removed in a newer version of the crate. Confusing features from a different crate. Using crate-level features that are only available as dependency features.
Related errors
- cannot add ` ` as a dependency to itself
- cannot override workspace dependency with
- cannot specify a git URL
- cannot specify a path
- dependency ( ) specified without providing a local path…
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/4850b3821417a768.
Report an issue: GitHub.
Appendix: source
Thrown at src/ops/cargo_add/mod.rs:241
.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 98a09e7e7d)