Rust: error[E0425]: cannot find value `X` in this scope

Quick answer

The value usually exists somewhere — Rust just can't see it from here. Check in order:

  • Typo or wrong case — the compiler often suggests the correct name.
  • Declared in a different block — an if/match/for body's bindings don't escape it.
  • Used before its let — Rust requires declaration before use for local bindings.
  • Struct field, missing self. — fields aren't bare identifiers inside a method.
  • Behind a disabled #[cfg(...)] — the item doesn't exist in this build at all.

The exact error string

fn main() {
    println!("{}", x);
}

// error[E0425]: cannot find value `x` in this scope
//  --> src/main.rs:2:20
//   |
// 2 |     println!("{}", x);
//   |                    ^ not found in this scope

The caret points at the exact identifier the compiler couldn't resolve, and when there's a plausible near-match rustc adds a suggestion beneath — a similarly-spelled binding, or (as covered below) a hint to prefix it with self.. Read that suggestion line before doing anything else; it's often the entire fix.

Cause 1: typo or wrong case

The simplest and most common cause — Rust identifiers are case-sensitive, and a one-character slip anywhere in the name is enough:

let user_count = 5;
println!("{}", User_count);
// error[E0425]: cannot find value `User_count` in this scope
//    = help: a local variable with a similar name exists: `user_count`

println!("{}", user_count);   // ✅

Cause 2: declared in a different scope

A binding only lives inside the block it was declared in. Once that block's closing } is reached, the name is gone — this is standard block scoping, but it's easy to lose track of across an if, match arm, or loop body:

fn describe(n: i32) {
    if n > 0 {
        let sign = "positive";
    }
    println!("{}", sign);   // ❌ sign only existed inside the if block
    // error[E0425]: cannot find value `sign` in this scope
}

fn describe_fixed(n: i32) {
    let sign = if n > 0 { "positive" } else { "non-positive" };   // ✅
    println!("{}", sign);
}

The fix is almost always to declare the binding in the outer scope that actually needs it — here, using if as an expression that produces the value, rather than a binding trapped inside one of its branches.

Cause 3: used before its own declaration

Unlike function items, const, and static — which are visible throughout their enclosing scope regardless of where they're written — a let binding is only visible after the line that declares it:

fn main() {
    println!("{}", total);   // ❌ used before its let
    let total = 42;
    // error[E0425]: cannot find value `total` in this scope
}

fn main_fixed() {
    let total = 42;
    println!("{}", total);   // ✅
}

This trips people coming from languages that hoist variable declarations. Rust doesn't hoist let bindings — move the declaration above every use.

Cause 4: forgot self. for a struct field

Inside a method, a struct's own fields aren't bare identifiers — they exist only as properties of self. Writing the field name alone looks up a local variable that was never declared:

struct Counter {
    count: i32,
}

impl Counter {
    fn increment(&mut self) {
        count += 1;   // ❌ `count` isn't a local — it's self.count
        // error[E0425]: cannot find value `count` in this scope
    }

    fn increment_fixed(&mut self) {
        self.count += 1;   // ✅
    }
}

The same applies to calling another method on the same instance — helper() instead of self.helper() — though that specific case is usually reported as an unresolved function call rather than E0425. When the value is a field, rustc's suggestion (when it fires) points you straight at the self. form.

Cause 5: gated behind a disabled #[cfg(...)]

Code behind a #[cfg(...)] attribute simply isn't compiled when the condition is false — as far as that build is concerned, it was never written. Referencing it unconditionally elsewhere in the crate fails only in configurations where the gate is off, which makes this the hardest cause to spot locally:

#[cfg(feature = "metrics")]
const MAX_RETRIES: u32 = 5;

fn run() {
    for _ in 0..MAX_RETRIES { /* ... */ }
    // error[E0425]: cannot find value `MAX_RETRIES` in this scope
    // (only when built WITHOUT the "metrics" feature enabled)
}

This compiles fine with cargo build --features metrics and fails without it — which is why it often first shows up in CI running a different feature combination than your local default. Either gate the usage site with the same #[cfg(...)], or move the constant out from behind the gate if it should always exist.

E0425 vs E0433 vs a missing use

All three look similar — "the compiler can't find my identifier" — but the fix differs by what kind of identifier failed:

ErrorWhat failed to resolveTypical fix
E0425 (this page)A bare value — variable, const, static, fn, called by plain nameFix scope/order/typo, or add self.
E0433A path (foo::Bar) — a crate, module, or type segmentAdd the crate to Cargo.toml, add use, or declare the local mod
E0432A use statement itself can't be resolvedSame family as E0433 — check the crate/module name and dependency

The quick test: does the unresolved name have a :: after it? If yes, you're looking at E0433, not this page.

Debugging checklist

Frequently Asked Questions

What does error[E0425]: cannot find value X in this scope mean?

Rust's compiler could not resolve X as any kind of value — a variable, constant, static, or function — visible from the point where you used it. It doesn't mean X doesn't exist anywhere in your project, only that it isn't reachable from this exact scope. The five usual causes are a typo, using it before its own let binding, declaring it in a different block, forgetting self. for a struct field, or the item being compiled out by a disabled cfg attribute.

How is E0425 different from E0433?

E0425 is for a bare identifier used as a value — a variable, constant, or function called by its plain name. E0433 is for a path — an identifier followed by ::, like foo::Bar — that fails to resolve because a crate, module, or use statement is missing. If your unresolved identifier has no :: after it, you have E0425; if it does, see error[E0433]: failed to resolve.

Why do I get E0425 right after adding an if let or match?

The value was almost certainly bound inside the if let or match arm's block, and you're trying to use it after that block ends. Rust's block scoping means a binding only lives until its enclosing { } closes. Move the code that needs the value inside the same block, or restructure to bind it in an outer scope first.

Why does Rust say cannot find value for a struct field I clearly have?

Inside a method, a struct's fields are not bare identifiers — they're only reachable through self. Writing count instead of self.count inside an impl block produces exactly this error, because count as a plain name isn't a local variable, constant, or function; it only exists as a field on self.

Can a #[cfg(...)] attribute cause this error?

Yes. Code behind a #[cfg(feature = "x")] or a platform-specific #[cfg(unix)] simply doesn't exist in a build where that condition is false — the compiler behaves as if you never wrote it. If a constant, function, or module only exists for certain cfg configurations, using it unconditionally elsewhere in the crate produces E0425 (or E0433 for a path) whenever it's built without that configuration.

More Rust & backend errors

Browse the full reference for Rust, Go, and Java errors — exact message, cause, and fix.

All Error References Rust E0433: failed to resolve Rust E0599: no method named
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.