#unsafe #cargo #plugin

app cargo-geiger

Detects usage of unsafe Rust in a Rust crate and its dependencies

23 unstable releases (9 breaking)

0.10.2 Jul 18, 2020
0.9.1 Jan 25, 2020
0.9.0 Dec 1, 2019
0.8.0 Nov 18, 2019
0.4.0 Jul 23, 2018

#18 in Cargo plugins

Download history 110/week @ 2020-06-01 55/week @ 2020-06-08 123/week @ 2020-06-15 54/week @ 2020-06-22 69/week @ 2020-06-29 54/week @ 2020-07-06 192/week @ 2020-07-13 174/week @ 2020-07-20 106/week @ 2020-07-27 75/week @ 2020-08-03 125/week @ 2020-08-10 105/week @ 2020-08-17 78/week @ 2020-08-24 77/week @ 2020-08-31 137/week @ 2020-09-07 58/week @ 2020-09-14

338 downloads per month


1.5K SLoC

cargo-geiger ☢️

Build Status unsafe forbidden

A program that list statistics related to usage of unsafe Rust code in a Rust crate and all its dependencies.

This cargo plugin is based on the code from two other projects: https://github.com/icefoxen/cargo-osha and https://github.com/sfackler/cargo-tree.


Try to find and use a system-wide installed OpenSSL library:

cargo install cargo-geiger

Or, build and statically link OpenSSL as part of the cargo-geiger executable:

cargo install cargo-geiger --features vendored-openssl


  1. Navigate to the same directory as the Cargo.toml you want to analyze.
  2. cargo geiger

Output example

Example output

Why even care about unsafe Rust usage?

When and why to use unsafe Rust is out of scope for this project, it is simply a tool that provides information to aid auditing and hopefully to guide dependency selection. It is however the opinion of the author of this project that libraries choosing to abstain from unsafe Rust usage when possible should be promoted.

This project is an attempt to create pressure against unnecessary usage of unsafe Rust in public Rust libraries.

Why the name?


Unsafe code and ionizing radiation have something in common, they are both inevitable in some situations and both should preferably be safely contained!

Known issues

  • Unsafe code inside macros are not detected. Needs macro expansion(?).
  • Unsafe code generated by build.rs are probably not detected.
  • More on the github issue tracker.


  • There should be no false negatives. All unsafe code should be identified. This is probably too ambitious, but scanning for #![forbid(unsafe_code)] should be a reliable alternative (implemented since 0.6.0). Please see the changelog.
  • An optional whitelist file at the root crate level to specify crates that are trusted to use unsafe (should only have an effect if placed in the root project).



  • Bugfix: Avoid panic and log warnings on parse failure. #105
  • Upgraded all dependencies.


  • Expose the cargo crate feature: vendored-openssl. #99
  • Upgraded all dependencies.


  • Upgraded all dependencies. #98


  • Bugfix: Avoid counting the same crate multiple times. #79
  • Upgraded cargo to 0.41. #85
  • Upgraded all dependencies.


  • Breaking change: Replaced structopt & clap with pico-args, to reduce compile times #77. As a result the -Z flag now requires quotes around its list of sub arguments, other than that there should be no changes to the CLI.


  • Bugfix: Count all expressions in unsafe functions and nested unsafe scopes, in geiger 0.4.1, #72 & #71.
  • Bugfix: Properly account for possibly patched dependencies #70.
  • Summary for each metrics column, #76.
  • Now requires all entry points for a crate to declare #[forbid(unsafe_code)] for it to count as crate-wide.
  • New optional scan mode --forbid-only. This mode doesn't require any calls to rustc and only requires parsing the entry point .rs files, making it much faster than the normal mode.
  • Updated dependencies.


  • Bugfix: Fix dependency collection for mixed workspaces #66.
  • Updated dependencies.


  • Updated dependencies to fix #59.


  • Bugfix: related to attributes, in geiger #57.
  • Updated all dependencies.


  • Updated all dependencies, geiger to 0.3.0.


  • A tiny readme fix.


  • There are now three crate scanning result variants #52:
    • 🔒 No unsafe usage found and all build target entry point .rs source files, used by the build, declare #![forbid(unsafe_code)]. Crates like this will be printed in green.
    • ❓ No unsafe usage found, but at least one build target entry point .rs file, used by the build, does not declare #[forbid(unsafe_code)]. Crates like this will be printed in the default terminal foreground color.
    • ☢️ Unsafe usage found. Crates like this will be printed in red, same as in the previous version.


  • Moved resusable parts, decoupled from cargo, to the new crate geiger. Main github issue: #30.
  • Some general refactoring and cleanup.
  • Merge pull request #46 from alexmaco/dependency_kind_control. add options to filter dependencies by kind; defaults to Kind::Normal.
  • Merge pull request #40 from jiminhsieh/rust-2018. Use Rust 2018 edition.


  • Bugfix: Merge pull request #33 from ajpaverd/windows_filepaths. Canonicalize file paths from walker.

  • Merge pull request #38 from anderejd/updated-deps. Updated deps and fixed build errors.


  • Merge pull request #28 from alexmaco/deps_upgrade. fix build on rust 1.30: upgrade petgraph to 0.4.13

  • Bugfix: Merge pull request #29 from alexmaco/invalid_utf8_source. fix handling source files with invalid utf8: lossy conversion to string


  • Filters out tests by default. Tests can still be included by using --include-tests. The test code is filted out by looking for the attribute #[test] on functions and #[cfg(test)] on modules.


  • Bugfix: Some bugfixes related to cargo workspace path handling.
  • Slightly better error messages in some cases.


  • Intercepts rustc calls and reads the .d files generated by rustc to identify which .rs files are used by the build. This allows a crate that contains .rs files with unsafe code usage to pass as "green" if the unsafe code isn't used by the build.
  • Each metric is now printed as x/y, where x is the unsafe code used by the build and y is the total unsafe usage found in the crate.
  • Removed the --compact output format to avoid some code complexity. A new and better compact mode can be added later if requested.


  • Table based output format #9.


  • Initial experimental versions.
  • Mostly README.md updates.


~811K SLoC