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/forbody'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:
| Error | What failed to resolve | Typical fix |
|---|---|---|
| E0425 (this page) | A bare value — variable, const, static, fn, called by plain name | Fix scope/order/typo, or add self. |
| E0433 | A path (foo::Bar) — a crate, module, or type segment | Add the crate to Cargo.toml, add use, or declare the local mod |
| E0432 | A use statement itself can't be resolved | Same 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
- ✓ Read the
help:suggestion first — rustc often names the fix directly - ✓ Check for a typo or case mismatch against the actual declaration
- ✓ Is the binding declared inside an
if/match/forblock you've since left? - ✓ Is the
letdeclaration physically below the line that uses it? - ✓ Inside an
implblock? Try prefixing withself. - ✓ Check for a
#[cfg(...)]on the declaration that might be disabled in this build - ✓ Identifier followed by
::? Wrong page — that's E0433 - ✓ Still stuck? rust-analyzer's "go to definition" on the closest similarly-named item will confirm whether it's a scope or a spelling problem
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.