Skip to content

Rust Error E0432: Unresolved Import

E0432 means one of your use lines points at something Rust can’t find. Maybe the crate isn’t in Cargo.toml yet, maybe there’s a small typo in the path, or maybe a file exists but Rust doesn’t know it’s a module. It looks scary, but it is almost always a one-line fix, and the compiler usually tells you which line. This page is part of the compiler errors guide.

error[E0432]: unresolved import `rand`
--> src/main.rs:1:5
|
1 | use rand::random_range;
| ^^^^ use of unresolved module or unlinked crate `rand`
|
= help: if you wanted to use a crate named `rand`, use `cargo add rand` to add it to your `Cargo.toml`

This is the program that produces it, in a fresh cargo new project with nothing under [dependencies]:

use rand::random_range;
fn main() {
let roll = random_range(1..=6);
println!("You rolled {roll}");
}

The text under the ^^^^ changes with the cause. Each of these is E0432, and each one points to a different fix below:

What the label says What usually went wrong Fix
use of unresolved module or unlinked crate crate missing from Cargo.toml, or a file with no mod line Fix 1 or Fix 3
could not find `collection` in `std` a typo in the middle of the path Fix 2
no `Hashmap` in `collections` a typo (or wrong case) in the last name Fix 2
could not find `inventory` in the crate root crate:: path to a module that isn’t declared Fix 3
no external crate the path starts in the wrong module Fix 4

A use line is a shortcut. use rand::random_range; says “from now on, random_range means the thing at rand::random_range”. Before Rust can make that shortcut, it has to walk the path one piece at a time: first find rand, then find random_range inside it.

The ^^^^ marks the first piece that failed. Here it’s rand, the very first segment, so Rust never even looked for random_range. The help: line guesses why: rand is a crate from crates.io, and this project hasn’t added it.

It’s like giving a taxi driver the address “12 Harbour Street, Springfeld”. If the town name is wrong, the driver can’t even start looking for the street.

Rust resolves every path when it compiles, not when the program runs. Nothing is loaded “just in case”. Your code can only see three kinds of things: crates listed in Cargo.toml (plus std), modules you declared with mod, and the items inside those. If a use line names something outside that set, Rust stops right away instead of guessing.

This is a good thing. A misspelled import in Python or JavaScript often fails only when that line finally runs, maybe in production. In Rust it can’t even build. It also means a crate you never added can never sneak into your program.

Since the 2018 edition, a use path starts in one of these places: the name of a crate (std, rand), crate (the root of your own crate), self (the current module), super (the parent module), or a module declared in the current module. The Modules lesson covers this in detail, and Cargo and crates explains dependencies.

Choose this when the first segment is a crate from crates.io, like rand, serde or regex, and the help: line mentions cargo add. This is the most common cause, especially when you copy code from a blog post. Run this in the folder that contains Cargo.toml:

Terminal window
cargo add rand

Cargo finds the newest version and adds a line to Cargo.toml for you:

[dependencies]
rand = "0.10.3"

Now the same code builds. This version prints a check instead of the roll itself, so the output is always the same:

use rand::random_range;
fn main() {
let roll = random_range(1..=6);
println!("Roll is between 1 and 6: {}", (1..=6).contains(&roll));
}

Output:

Roll is between 1 and 6: true
▶ Try it Yourself

Two things trip people up here. First, crate names with a dash use an underscore in code: you cargo add tracing-subscriber but write use tracing_subscriber::.... Second, if the crate is a dependency of your workspace, it still has to be listed in the Cargo.toml of the package that uses it.

Choose this when the label says could not find `X` in `Y` or no `X` in `Y`. Something in the middle or at the end of the path is misspelled. A classic one:

error[E0432]: unresolved import `std::collection`
--> src/main.rs:1:10
|
1 | use std::collection::HashMap;
| ^^^^^^^^^^ could not find `collection` in `std`

The module is collections, with an s. Names are case-sensitive too: use std::collections::Hashmap; fails with no `Hashmap` in `collections`, and rustc adds help: a similar name exists in the module with the right spelling. The fixed import:

use std::collections::HashMap;
fn main() {
let mut stock: HashMap<&str, u32> = HashMap::new();
stock.insert("apples", 12);
println!("{:?}", stock.get("apples"));
}

Output:

Some(12)
▶ Try it Yourself

If you’re not sure of the exact path, search the standard library docs. The page for each item shows its full path at the top. See HashMaps for more on this type.

Choose this when you created a new file, say src/inventory.rs, and use inventory::... can’t find it. In Rust a file is not a module until a parent file declares it. Your project looks like this:

src/
├── main.rs use inventory::count_items; ← no `mod inventory;`
└── inventory.rs pub fn count_items() -> u32 { 42 }

And rustc says exactly what’s missing:

error[E0432]: unresolved import `inventory`
--> src/main.rs:1:5
|
1 | use inventory::count_items;
| ^^^^^^^^^ use of unresolved module or unlinked crate `inventory`
|
help: to make use of source file src/inventory.rs, use `mod inventory` in this file to declare the module
|
1 + mod inventory;
|

Add mod inventory; at the top of src/main.rs (or src/lib.rs, if the module belongs to your library). Writing use crate::inventory::count_items; instead doesn’t help; it fails with could not find `inventory` in the crate root, because the module still isn’t declared.

On the Playground everything lives in one file, so here the module is written inline with mod inventory { ... }. It works exactly like the separate file:

mod inventory {
pub fn count_items() -> u32 {
42
}
}
use inventory::count_items;
fn main() {
println!("Items in stock: {}", count_items());
}

Output:

Items in stock: 42
▶ Try it Yourself

Declare each module once, in its parent. Other files then reach it with use crate::inventory::.... Don’t add mod inventory; to every file that uses it.

Fix 4: Start the path from the right place

Section titled “Fix 4: Start the path from the right place”

Choose this when the import is inside a module and the item lives in a different module of your own crate. Here receipt is inside shop and wants shop::store_name:

mod shop {
pub fn store_name() -> &'static str {
"Ferris Fruits"
}
pub mod receipt {
use store_name; // ❌ looks in the wrong place
pub fn header() -> String {
format!("== {} ==", store_name())
}
}
}
error[E0432]: unresolved import `store_name`
--> src/main.rs:7:13
|
7 | use store_name; // ❌ looks in the wrong place
| ^^^^^^^^^^ no external crate `store_name`

A bare name at the start of a use path means “a crate, or something declared right here in this module”. store_name is neither, so Rust looked for a crate with that name. Tell it where to start instead:

Prefix Starts from Example
crate:: the root of your crate (main.rs or lib.rs) use crate::shop::prices::price_of;
super:: the parent module use super::store_name;
self:: the current module use self::lines::line;

All three in one program:

mod shop {
pub fn store_name() -> &'static str {
"Ferris Fruits"
}
pub mod prices {
pub fn price_of(item: &str) -> u32 {
if item == "apple" { 3 } else { 5 }
}
}
pub mod receipt {
use super::store_name; // parent module: shop
use crate::shop::prices::price_of; // from the crate root
use self::layout::line; // child of this module
mod layout {
pub fn line(item: &str, price: u32) -> String {
format!("{item}: {price}")
}
}
pub fn print(item: &str) {
println!("== {} ==", store_name());
println!("{}", line(item, price_of(item)));
}
}
}
fn main() {
shop::receipt::print("apple");
}

Output:

== Ferris Fruits ==
apple: 3
▶ Try it Yourself

use layout::line; would also work here, because layout is declared in the current module; self:: just makes that explicit. When in doubt, crate:: with the full path always works from anywhere in your crate, and rustc often suggests it: help: a similar path exists followed by the crate:: version.

Code written for an older crate version. Many tutorials use rand 0.8. With rand 0.10 you get:

error[E0432]: unresolved import `rand::thread_rng`
--> src/main.rs:1:5
|
1 | use rand::thread_rng;
| ^^^^^^^^^^^^^^^^ no `thread_rng` in the root

Fix: check the crate’s docs on docs.rs for the version in your Cargo.toml. Here the new name is rand::rng(). See Random numbers.

A package with both main.rs and lib.rs. They are two separate crates. Inside main.rs, crate:: means the binary, so use crate::inventory::count_items; fails with could not find `inventory` in the crate root even though lib.rs has pub mod inventory;. Fix: use the package name, use shop_app::inventory::count_items; (with dashes turned into underscores).

The item exists but is private. That’s a different error, E0603, not E0432:

error[E0603]: function `count_items` is private
--> src/main.rs:7:16
|
7 | use inventory::count_items;
| ^^^^^^^^^^^ private function

Fix: add pub in front of the fn (and in front of any mod on the way, since a private module gives module `prices` is private). See Modules.

  • E0433: a path inside your code (like HashMap::new() or rand::rng()) can’t be resolved. Same causes, but not on a use line.
  • E0425: cannot find a value or function, often fixed by the same use line.
  • E0603: the import was found but is private. Add pub.
  • E0463: can't find crate, which you get from extern crate rand; when the crate isn’t in Cargo.toml.
  • All compiler errors: the full list of error pages.

Quick check

1. You copied use serde::Serialize; into a new project and get E0432 that says the crate serde is unresolved or unlinked. What's the fix?

2. You created src/billing.rs, but use billing::total; in main.rs fails. What's missing?

3. Inside mod shop { mod receipt { ... } }, how does receipt import a function defined directly in shop?

Score: 0 / 3