rust-lang/cargo · error

target ` ` in package ` ` requires the features: Consider…

Error message

target `{}` in package `{}` requires the features: {}
Consider enabling them by passing, e.g., `--features="{}"`

What it means

Thrown when a build target (binary, example, bench, test) declares `required-features` in Cargo.toml, but the active feature set does not satisfy all of them, AND the target is not skippable. Cargo computes the unavailable features by subtracting the enabled feature set from the target's `required-features`; if any remain and `requires_features` is true (the default-filter path where targets are not silently filterable), it aborts rather than silently dropping the target. The error names the offending target, package, and the exact features to enable.

Solutions

  1. Enable the missing feature(s): `cargo build --features="<feature>"` (or space/comma-separated list) exactly as the message prints in the `Consider enabling` hint.
  2. If the target should always build, remove or broaden the `required-features` list for that target in Cargo.toml so the default feature set satisfies it.
  3. Make the feature default-on: add it to `[features] default = ["gui"]` so normal builds include it.
  4. If you intended to skip the target, build a specific other target explicitly with `--bin <name>` / `--example <name>` (still needs the feature) or exclude the package.
  5. In CI, mirror the feature set the target expects — e.g. `cargo build --all-features` or `--features` matching the crate's documented matrix.

Example fix

// before (Cargo.toml)
[[bin]]
name = "tool"
required-features = ["gui"]
// run: cargo build   -> error

// after — command
//   cargo build --features gui

// after — or make it default
[features]
default = ["gui"]
gui = ["dep:some_gui_lib"]
Defensive patterns

Strategy: validation

Validate before calling

// Before building, compute whether the enabled feature set satisfies each target's required-features.
fn missing_required_features(
    enabled: &std::collections::HashSet<String>,
    required: &[String],
) -> Vec<String> {
    required.iter().filter(|f| !enabled.contains(*f)).cloned().collect()
}

// usage: if !missing.is_empty() { eprintln!("pass --features='{}'", missing.join(" ")); }

Type guard

// Narrow a target description before selecting it for a default build.
struct TargetSpec<'a> { name: &'a str, required_features: &'a [String] }
fn is_buildable_with(target: &TargetSpec, features: &std::collections::HashSet<String>) -> bool {
    target.required_features.iter().all(|f| features.contains(f))
}

Prevention

When it happens

Trigger: Running `cargo build`/`cargo run`/`cargo test` (default target selection, i.e. `required_features_filterable == false`) against a package containing a `[[bin]]`, `[[example]]`, `[[bench]]`, or `[[test]]` target with `required-features = ["..."]`, without passing `--features` to enable them. Concretely: a target like `[[bin]]\nname = "tool"\nrequired-features = ["gui"]` built with `cargo build` instead of `cargo build --features gui`.

Common situations: Adding a feature-gated binary/example to a workspace crate and forgetting to enable the feature in CI. Copying a target with `required-features` from another project. Upgrading a dependency whose feature name changed. Running `cargo run --bin gated-bin` directly. CI invoking plain `cargo build --workspace` where one member has required-feature targets.

Related errors


AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11). Data as JSON: /api/errors/8c442ee4d5c13f78. Report an issue: GitHub.

Appendix: source

Thrown at src/ops/cargo_compile/unit_generator.rs:753

                            self.has_dev_units,
                            self.requested_kinds,
                            self.target_data,
                            ForceAllTargets::No,
                        )
                    });
                    rf.iter().filter(|f| !features.contains(*f)).collect()
                }
                None => Vec::new(),
            };
            if target.is_lib() || unavailable_features.is_empty() {
                units.extend(self.new_units(pkg, target, mode));
            } else if requires_features {
                let required_features = target.required_features().unwrap();
                let quoted_required_features: Vec<String> = required_features
                    .iter()
                    .map(|s| format!("`{}`", s))
                    .collect();
                anyhow::bail!(
                    "target `{}` in package `{}` requires the features: {}\n\
               Consider enabling them by passing, e.g., `--features=\"{}\"`",
                    target.name(),
                    pkg.name(),
                    quoted_required_features.join(", "),
                    required_features.join(" ")
                );
            }
            // else, silently skip target.
        }
        let mut units: Vec<_> = units.into_iter().collect();
        self.unmatched_target_filters(&units)?;

        // Keep the roots in a consistent order, which helps with checking test output.
        units.sort_unstable();
        Ok(units)
    }

View on GitHub (pinned to eb98b54bc9)