NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #4396 most downloaded on crates.io
Cargo plugin to help you manage large dependency graphs
Last release 3 months ago
09 Jul 2026
Ships fairly regularly
a new release about every 5 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
7 years old
118 releases · first in 2019
PR#881 refactored the CLI, moving some duplicated options/flags into the root and removing several deprecated options/flags/values. See the PR for a f…
bans.std-replacements lint which checks the graph for crates.io sourced crates that have been partially or fully replaced in std and/or core.One column per quarter.
PR#883 fixed snapshot filenames on Windows which caused the release binary publish to fail.
PR#881 refactored the CLI, moving some duplicated options/flags into the root and removing several deprecated options/flags/values. See the PR for a f…
bans.std-replacements lint which checks the graph for crates.io sourced crates that have been partially or fully replaced in std and/or core.PR#866 added sources.unused-allowed-org
PR#864 fixed matching of ^ and ~ with on prerelease versions for when checking if a crate is affected by an advisory. As of the time of the PR, this l
^ and ~ with on prerelease versions for when checking if a crate is affected by an advisory. As of the time of the PR, this literally affected none of published versions of any crate with an advisory, but this just ensures such a case will be handled in the future.PR#860 updated crates, resolving krates#111 .
PR#854 resolved #854 by removing environment variables that affect repo paths before cloning or fetching the advisory database.
PR#857 fixed a segfault reported in #855 .
PR#847 and PR#848 resolved #846 , which was an advisory parsing bug that only affected Windows.
PR#847 resolved #846, which only affected Windows.
PR#845 fixed structural issues with SARIF output, resolving #818. Thanks @KyleChamberlin!
PR#833 fixed an issue where the maximum advisory database staleness was over 14 years instead of the intended 90 days.
--filter-platform when collecting cargo metadata if only a single target was requested either in the config or via the command line.--frozen would not disable fetching of the advisory DB, resolving #759.krates was updated to resolve two issues with crates being pruned from the graph used when running checks. Resolving these two issues may mean that updating cargo-deny may highlight issues that were previously hidden.
lib target renamed by the package author.gix in favor of shelling out to git. This massively improves build times and eases maintenance as gix bumps minor versions quite frequently. If cargo-deny is used in an environment that for some reason allows internet access but doesn't have git available, the advisory database would need to be updated before calling cargo-deny.rustsec in favor of manually implemented advisory parsing and checking, with a nightly cron job that checks that the implementation exactly matches rustsec on the official rustsec advisory db.PR#802 made relative paths passed to --config be resolved relative to the current working directory (rather than the resolved manifest path's director
--config be resolved relative to the current working directory (rather than the resolved manifest path's directory).gix, reqwest, and tame-index to newer versions. The reqwest 0.13 changes means it is no longer possible to choose the source of root certificates for gix, so that decision is now left to rustls-platform-verifier. The native-certs feature has thus been removed, and cargo-deny no longer defaults to using webpki-roots.--config, resolving #748.[bans.allow-workspace] to allow workspace crates while denying all external crates.[licenses.include-build] to toggle whether build dependencies are included in the license check.[advisories.unused-ignored-advisory] to disable the warning when an advisory is ignored but not encountered in the crate graph.[advisories.unsound] to determine which crates can show unsound advisories, similarly to the unmaintained field. Defaults to workspace crates, ignoring unsound advisories for transitive dependencies, resolving #824.PR#817 resolved #816 by making most license integration tests just return success if I or CI am not the one running them.
PR#814 now allows deprecated license identifiers if they are detected from text, which was broken in 0.18.7. Additionally, when a GNU license (GPL, AG…
-or-later variant, arbitrarily chosen as it is impossible to distinguish between the variants for a particular license version. This means if the license detected is actually wrong (eg. GPL-3.0-or-later is detected when the code is actually licensed under GPL-3.0-only), the license should instead be clarified to the correct one. Resolves #813.PR#812 updated spdx to 0.13, allowing cargo-deny to remove the askalono dependency but still support license detection.
spdx to 0.13, allowing cargo-deny to remove the askalono dependency but still support license detection.PR#789 changed it so that release binaries are now built with LTO.
PR#779 added the --metadata-path argument to use a cargo metadata JSON file instead of calling cargo metadata, resolving #777.
--metadata-path argument to use a cargo metadata JSON file instead of calling cargo metadata, resolving #777.sources.unused-allow-source to allow configuration of the lint level when a source is allowed but not used by any crate in the graph, closing #781./ is no longer corrected to OR, and if the license expression is found in the package's manifest, that span is used in diagnostic messages instead of the synthesized manifest.spdx to a new version that forces all GNU licenses to be exactly equal when comparing license expressions to licensee expressions, which is incredibly pedantic, but means the license comparison is entirely in the hands of the user so that I no longer have to deal with GNU licenses.PR#773 changed cargo-deny's duplicate detection to automatically ignore versions whose only dependent is another version of the same crate.
PR#753 resolved #752 by adding back the advisories.unmaintained config option. See the docs for how it can be used. The default matches the current be
advisories.unmaintained config option. See the docs for how it can be used. The default matches the current behavior, which is to error on any unmaintained advisory, but adding unmaintained = "workspace" to the [advisories] table will mean unmaintained advisories will only error if the crate is a direct dependency of your workspace.PR#749 updated krates to pull in the fix for EmbarkStudios/krates#100.
krates to pull in the fix for EmbarkStudios/krates#100.PR#746 changed the directory naming of advisory databases, again, so the name uses the last path component and a different, but also stable, hashing a
https://github.com/rustsec/advisory-db will now be placed in $CARGO_HOME/advisory-dbs/advisory-db-3157b0e258782691.PR#745 updated tame-index to 0.18.0 so that cargo 1.85.0 is transparently supported along with older cargo versions.
PR#742 updated gix to 0.70, to resolve RUSTSEC-2025-0001.
gix to 0.70, to resolve RUSTSEC-2025-0001.PR#721 updated rust-version to 1.81.0 to accurately reflect the minimum rust version required to compile, resolving #720.
PR#703 resolved #696 by no longer emitting errors when failing to deserialize deprecated fields, and removed some lingering documentation that wasn't…
krates -> 0.17.5, fixing an issue where cargo-deny could panic due to incorrectly resolving features for different versions of the same crate referenced by a single crate.--exclude-unpublished CLI argument or the graph.exclude-unpublished config field. Thanks @Tastaturtaste!PR#691 fixed an issue where workspace dependencies that used the current dir '.' path component would incorrectly trigger the unused-workspace-depende
unused-workspace-dependency lint.vulnerability - Vulnerability advisories are now deny by default
[advisories]The following fields have all been removed in favor of denying all advisories by default. To ignore an advisory the ignore field can be used as before.
vulnerability - Vulnerability advisories are now deny by defaultunmaintained - Unmaintained advisories are now deny by defaultunsound - Unsound advisories are now deny by defaultnotice - Notice advisories are now deny by defaultseverity-threshold - The severity of vulnerabilities is now irrelevant[licenses]The following fields have all been removed in favor of denying all licenses that are not explicitly allowed via either allow or exceptions.
unlicensed - Crates whose license(s) cannot be confidently determined are now always errors. The clarify field can be used to help cargo-deny determine the license.allow-osi-fsf-free - The OSI/FSF Free attributes are now irrelevant, only whether it is explicitly allowed.copyleft - The copyleft attribute is now irrelevant, only whether it is explicitly allowed.default - The default is now deny.deny - All licenses are now denied by default, this field added nothing.bans.workspace-dependencies section. This is an unannounced breaking change but is fairly minor and 0.15.0 was never released on github actions so the amount of people affected by this will be (hopefully) small. This also makes the workspace duplicate detection off by default since the field is optional, but makes it so that if not specified workspace duplicates are now deny instead of warn.PR#681 fixed #680 by always stripping .git from urls when matching sources to resolved nodes as they are allowed, but (generally) have no semantic mea
PR#673 added linting of [workspace.dependencies], resolving #436 and #525.
[workspace.dependencies], resolving #436 and #525.
workspace-duplicates, which allows checking for missing usage of workspace = true for direct workspace dependencies that are used more than once in the workspace.unused-workspace-dependencies, which allows checking for dependencies declared in [workspace.dependencies] that aren't actually used.bans.wildcards lint. Previously fake cargo manifests were created that weren't even necessarily valid toml files, however now the actual cargo manifests are used, meaning that the lint will now point to the correct file and line location of the dependency declaration that uses a wildcard.gix -> 0.64 (and tame-index).PR#663 updated some crates, notably gix -> 0.63 (and tame-index).
gix -> 0.63 (and tame-index).PR#657 resolved #652 by fixing an issue where the exit code was incorrect if logging was disabled.
PR#653 updated jobserver -> 0.1.30
PR#643 resolved #629 by making the hosted git (github, gitlab, bitbucket) org/user name comparison case-insensitive. Thanks @pmnlla!
cfg()/triple targets could cause features to be resolved incorrectly and thus crates to be not pulled into the graph used for checking.PR#642 resolved #641 by pinning gix-transport (and its unique dependencies) to 0.41.2 as a workaround for cargo install not using the lockfile. See th
gix-transport (and its unique dependencies) to 0.41.2 as a workaround for cargo install not using the lockfile. See this issue for more information.PR#639 updated tame-index to avoid an error if you don't used --locked.
--locked.PR#638 resolved #636 by updating krates.
PR#631 improved the diagnostic for when the yank check fails due to some issue with retrieving or reading the index information.
PR#626 resolved #625 by explicitly checking that a license identified as Pixar was actually (probably) the Pixar license, instead of a normal Apache-2
PR#618 added metadata notes to diagnostics when a license is rejected, as well as removing span information for accepted licenses unless the log level
info or higher to make the diagnostic clearer by default.PR#617 resolved #576 by updating the SPDX license list to 3.23.
…changed via the CLI. It also introduced the deprecated diagnostic code.
PR#606 and PR#611 together deprecated several fields listed below. See PR#611 for how to change your config to opt-in to the new behavior that will be…
targets, exclude, all-features, features, no-default-features, and exclude into the [graph] table.feature-depth into the [output] table.advisories.db-path, which expands support beyond just ~ to include environment variable expansion.toml and serde with toml-span.name = "<crate_name>", version = "<requirements>" used to target specific crates into either a plain package spec string or the simpler crate = "<package spec>".reason = "<reason>" field to many fields within the configuration that are provided in diagnostics. [bans.deny] also has an additional use-instead = "<url/crate_name>". PR#610 did this for the advisories.ignore field.[advisories.ignore] array.[advisories]
vulnerabilityunmaintainedunsoundnoticeseverity-threshold[licenses]
unlicensedallow-osi-fsf-freecopyleftdefaultdenyPR#599 resolved #488 by treating git and path sources differently. Thanks @kpreid!
PR#596 updated krates _again_ to pull in krates#77.
PR#594 updated krates _again_ to pull in krates#75.
PR#592 updated krates _again_ to pull in krates#73.
PR#591 updated krates _again_ to pull in krates#71.
PR#590 updated krates to fix an issue with crates that directly have a dependency on 2 or more versions of the same crate.
krates to fix an issue with crates that directly have a dependency on 2 or more versions of the same crate.wrapper crate for a banned crate does not have a dependency on that crate.gix and tame-index.PR#588 resolved an issue introduced in [0.14.4] where features that reference dev-only dependencies in non-workspace crates would cause a panic.
PR#586 resolved 2 issues with crate graph creation, see krates#60 and krates#64 for more details.
PR#566 updated tame-index to obtain OS file locking, resolving #537. This change means that cargo-deny should not encounter issues such as those descr
tame-index to obtain OS file locking, resolving #537. This change means that cargo-deny should not encounter issues such as those described in this rustsec issue since we no longer use gix::lock locking advisory databases, and makes reading the crates.io index safer by respecting the lock used by cargo itself.PR#545 added the ability to specify additional license exceptions via additional configuration files.
bans.build configuration option, opting in to checking for file extensions, native executables, and interpreted scripts. This resolved #43.dev-dependencies are handled. By default, crates that are only used as dev-dependencies (ie, there are no normal nor build dependency edges linking them to other crates) will no longer be considered when checking for multiple-versions violations. This can be re-enabled via the bans.multiple-versions-include-dev config field. Additionally, licenses are no longer checked for dev-dependencies, but can be re-enabled via licenses.include-dev the config field. dev-dependencies can also be completely disabled altogether, but this applies to all checks, including advisories and sources, so is not enabled by default. This behavior can be enabled by using the exclude-dev field, or the --exclude-dev command line flag. This change resolved #322, #329, #413 and #497.native-certs feature flag that can enable the OS native certificate store.bans.allow-build-scripts to bans.build.allow-build-scripts. bans.allow-build-scripts is still supported, but emits a warning.PR#544 updated dependencies, notably tame-index 0.2.5 which fixed this issue
tame-index 0.2.5 which fixed this issueadvisories, but no other, check fails.[PR#520] resolved #522 by completely removing all dependencies upon git2 and openssl. This was done by transitioning from git2 -> gix for all git oper
git2 and openssl. This was done by transitioning from git2 -> gix for all git operations, both directly in this crate, as well as replacing crates-index with tame-index.1.65.0 -> 1.70.0cargo update -p <crate_name>)" when an advisory is detected for a crate. Thanks @Victor-N-Suadicani!git2 to gix.osi and fsf options to licenses.allow-osi-fsf-free. Thanks @zkxs!gix's file-based locking to ensure that only one process has mutable access to an advisory database repo at a time.standalone. This is due to cargo still being in transition from git2 -> gix and having no way to compiled without OpenSSL. Once cargo is a better state with regards to this we can add back that feature.PR#506 replaced atty (unmaintained) with is-terminal. Thanks @tottoto!
atty (unmaintained) with is-terminal. Thanks @tottoto!PR#504 (though really PR#365) resolved #350 by adding the deny-multiple-versions field to bans.deny entries, allowing specific crates to deny multiple
deny-multiple-versions field to bans.deny entries, allowing specific crates to deny multiple versions while allowing/warning on them more generally. Thanks @leops!.cargo. Thanks @DJMcNab!PR#491 resolved #490 by building libgit2 from vendored sources instead of relying on potentially outdated packages.
PR#485 added this project and repository to our Security Bug Bounty Program and has Private vulnerability reporting enabled. See `SECURITY.md` for mor…
clap, cargo, and git2SECURITY.md for more details.allow-wildcard-paths, fixing #488 by allowing wildcards to be denied, but allowing them for internal, private crates. Thanks @sribich!branch=master would be incorrectly categorized as not specifying the branch (ie use HEAD of default branch).Your coding agent can read these notes before it upgrades. Set up the MCP server →