How to fix Rust E0433 failed to resolve

Fix Rust E0433 by adding missing dependencies to Cargo.toml or correcting the module path in your use statement.

When the compiler says "I don't know that"

You just copied a cool snippet from a blog post. It uses reqwest to fetch a URL, or serde to parse JSON. You paste it into main.rs, hit run, and the compiler screams:

error[E0433]: failed to resolve: use of undeclared crate or module `reqwest`
 --> src/main.rs:1:5
  |
1 | use reqwest::Client;
  |     ^^^^^^^ use of undeclared crate or module `reqwest`

You stare at the screen. The code looks fine. The crate is definitely a thing. You've seen it on crates.io. What went wrong?

E0433 is the compiler's way of saying it cannot find the name you used. It doesn't know about the crate, or it doesn't know about the module inside your project. This error is the most common hurdle for new Rust developers because Rust separates declaring dependencies from using them. The compiler trusts Cargo to tell it what exists. If Cargo hasn't spoken up, the compiler assumes the name is imaginary.

The kitchen and the supplier

Think of your Rust project as a kitchen. You have your own ingredients in the pantry: the standard library and the code you wrote. You want to use a fancy spice blend from a neighbor's pantry. That neighbor is an external crate.

You cannot just reach over the fence and grab the spice. The kitchen has a strict rule: only approved ingredients are allowed. You have to ask the head chef, Cargo, to bring the spice into your kitchen. Cargo reads your shopping list, Cargo.toml. If the spice is on the list, Cargo fetches it and places it on your counter. If it's not on the list, Cargo ignores it.

When you write use reqwest::Client, you are asking the compiler to use the Client tool from the reqwest spice jar. If reqwest isn't on your shopping list, the compiler looks at the counter, sees no jar, and throws E0433. The compiler never checks crates.io. It only knows what Cargo told it.

Minimal example: missing dependency

The most common cause of E0433 is a missing entry in Cargo.toml. You can have the use statement perfect, but if the dependency is absent, the build fails.

Here is a program that tries to generate a random number. It fails immediately because rand is not declared.

// src/main.rs

// This line asks the compiler to bring Rng into scope.
// It fails if the 'rand' crate is not available.
use rand::Rng;

/// Generates a random number between 1 and 100.
fn main() {
    // thread_rng creates a local random number generator.
    // gen_range picks a value within the range.
    let secret_number = rand::thread_rng().gen_range(1..=100);
    println!("The secret number is: {secret_number}");
}

Running this produces E0433. The fix is to add rand to the dependencies.

# Cargo.toml

[package]
name = "my_app"
version = "0.1.0"
edition = "2021"

[dependencies]
# Add rand to the shopping list.
# Cargo will download this crate and tell the compiler it exists.
rand = "0.8"

After adding the dependency, Cargo downloads rand, and the compiler resolves the name. The code compiles.

Convention aside: modern Rust workflows use cargo add to avoid manual editing errors. Run cargo add rand in your terminal. Cargo updates Cargo.toml for you and ensures the version syntax is correct. This saves time and prevents typos in version numbers.

How Rust finds names

Understanding name resolution helps you fix E0433 faster. Rust resolves names by searching scopes in a specific order. When you write a name like Client or utils, the compiler looks in these places:

  1. The current scope. Variables and functions defined right here.
  2. Parent scopes. Blocks or functions wrapping the current code.
  3. The crate root. Items declared at the top level of your crate.
  4. External crates. Dependencies declared in Cargo.toml.

The use statement creates a shortcut. It imports a name from a longer path into the current scope. Without use, you must write the full path. If you remove use rand::Rng, you can still call rand::thread_rng() because rand is an external crate available at the root. The use is optional for convenience, not for existence.

If the compiler cannot find the name in any of these scopes, it emits E0433. The error message usually tells you exactly what it tried to resolve. "Use of undeclared crate" means the top-level name is missing. "Use of undeclared module" means a sub-path is missing.

Realistic example: module structure errors

E0433 often strikes when you split code across multiple files. Rust uses a module system to organize code. Modules are declared with the mod keyword. If you forget to declare a module, the compiler doesn't know the file exists.

Consider a project with a helper module.

// src/lib.rs

// Declares a module named 'utils'.
// Rust looks for src/utils.rs or src/utils/mod.rs.
mod utils;

/// Calculates the area of a rectangle using the helper.
pub fn area(width: f64, height: f64) -> f64 {
    // Calls the helper function from the utils module.
    // This works because 'utils' is declared above.
    utils::calculate_area(width, height)
}
// src/utils.rs

/// Computes width times height.
pub fn calculate_area(w: f64, h: f64) -> f64 {
    w * h
}

If you delete mod utils; from lib.rs, the compiler never sees utils.rs. The line utils::calculate_area triggers E0433. The file exists on disk, but the module system hasn't wired it into the crate.

Another common trap is typos in paths. Rust is case-sensitive. Utils is not utils. Rng is not rng. If you type use rand::rng;, you get E0433 because the type is Rng. The compiler does not fuzzy-match names. It expects exact matches.

Pitfalls and edge cases

E0433 has several flavors. The error message points to the culprit, but the fix varies.

Feature flags hide modules. Some crates split functionality into optional features. If a feature is disabled, the corresponding module or macro might not exist. This is common with serde. The derive macro lives behind a feature flag.

[dependencies]
# Without the 'derive' feature, the Serialize macro is unavailable.
serde = { version = "1.0", features = ["derive"] }

If you omit features = ["derive"], using #[derive(Serialize)] fails with E0433. The macro is undeclared. The crate is present, but the specific tool you need is locked behind a feature. Check the crate documentation for required features.

Workspaces and path dependencies. In a workspace, crates reference each other using path dependencies. If the path is wrong, the dependency fails to resolve.

[dependencies]
# References a sibling crate in the workspace.
# If the path is incorrect, E0433 occurs.
my_lib = { path = "../my_lib" }

If my_lib is actually in ../lib, the path is wrong. Cargo cannot find the crate, so the compiler never sees it. Verify paths in workspace setups.

Legacy extern crate. Old Rust tutorials sometimes show extern crate foo;. This was required in Rust editions before 2018. Modern Rust editions automatically declare dependencies from Cargo.toml. You rarely need extern crate anymore. If you see it in old code, it is usually redundant. Removing it won't fix E0433, but adding it unnecessarily can confuse readers. Stick to use statements for imports.

Re-exports and visibility. Sometimes a module exists, but the item you want is not re-exported. If a crate has an internal module structure that doesn't expose a name at the top level, you might need to dig deeper. Check the documentation for the public API. If the docs don't show the path, the path might be private or non-existent.

Trust the documentation. If the docs show use foo::bar::Baz, use that exact path. Deviating from the documented path leads to E0433.

Decision matrix

Use the right fix for the specific cause of E0433.

Check your Cargo.toml when the error mentions an external crate you haven't added yet. Add the dependency with cargo add or manual entry.

Check your use statements when the crate is in Cargo.toml but the compiler still complains. Verify the path matches the documentation. Fix typos and case sensitivity.

Check module declarations (mod foo;) when you're trying to access code in another file within your own project. Ensure the module is declared in the parent file and the path is correct.

Check feature flags when the crate documentation mentions optional modules or macros. Enable the required feature in Cargo.toml.

Check workspace paths when you're using path dependencies between crates. Verify the relative path points to the correct directory.

Check for renamed crates when the error persists despite correct setup. Some crates change names over time. Search crates.io for the current name.

Where to go next

E0433 is a visibility problem, not a logic problem. Fix the path, fix the error. The compiler is telling you exactly what it can't see. Make it visible, and the build succeeds.