It can, but not reliably. Setting default-features = false stops your crate from requesting a dependency's defaults, yet Cargo builds each dependency once with the union of all features any package asks for. If another crate in the graph wants the defaults, they come back.
Definitions
A feature is an optional part of a crate, switched on by name. Default features are the set enabled when you do not say otherwise. Feature unification is Cargo's rule of building a dependency once, with every feature requested by anyone in the graph.
What the documentation says
The Cargo reference states that defaults can be disabled with the false setting, then notes this does not guarantee they stay off, because another package may depend on the same crate with defaults enabled. It also says features are meant to be additive: enabling a feature should not remove functionality.
Resolver 2
Setting resolver = "2" changes unification in three ways:
| Case | With resolver 2 |
|---|---|
| Platform specific dependencies for targets you are not building | Their features are ignored |
| Build dependencies and proc macros | Do not share features with normal dependencies |
| Dev dependencies | Do not turn on features unless building a target that needs them |
The cost is that a crate may be built more than once with different features, which raises build time. The reference points to the duplicates view of cargo tree for finding these.
Why it matters for security
Every enabled feature is more compiled code, and sometimes more dependencies. A network or compression feature you never use still brings parsers, and parsers are where many memory safety and denial of service bugs live. Fewer enabled features means less code to be affected by an advisory.
But do not overclaim. Whether a feature removes the vulnerable code depends on that advisory. Read which feature gates the affected function.
Steps to trim safely
- List what is enabled and why:
cargo tree -e features -i dependency_name
- Find the chain that enabled the feature you do not need.
- If your own manifest caused it, disable defaults and list only the features you use.
- If a parent caused it, open an issue upstream or accept it with a note.
- Build, test, and re-run the tree to confirm the feature is gone.
- Record the result so a later edit does not undo it.
A caution on testing
Features are additive, so a crate must work with any combination. If you remove a default feature and something breaks, that usually means your code relied on it implicitly. Add it explicitly rather than turning defaults back on.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how knowing which code is used changes what you fix first.
Quick check
Does a build dependency share features with my runtime dependency?
With resolver 2 it does not. Older resolver behavior unified them.
Is disabling defaults enough to mark an advisory not affected?
No. Confirm the affected code is gated by a feature that is truly off in your build.
Safeguard reachability analysis can help separate affected code from code you never call, and a free scan is available at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.