Rust Compiler Errors Explained
Got a red error from the Rust compiler and you’re not sure what it wants? You’re in the right place. Every Rust developer sees these errors, often many times a day. The good news: there are only a handful you’ll meet again and again, and once you know them, they stop being scary.
Each page below takes one error code, shows the real message, explains it in plain words, and gives you fixes you can run in your browser.
The most common errors
Section titled “The most common errors”| Error | What the compiler says | In plain words |
|---|---|---|
| E0382 | borrow of moved value | You gave a value away, then tried to use it again |
| E0502 | cannot borrow as mutable because it is also borrowed as immutable | You’re changing something while someone is still reading it |
| E0499 | cannot borrow as mutable more than once at a time | Two places want to change the same thing at once |
| E0308 | mismatched types | You gave one type where another was expected |
| E0277 | the trait bound is not satisfied | A type can’t do something you asked of it (print, compare, add…) |
| E0106 | missing lifetime specifier | Rust can’t tell how long a returned reference stays valid |
| E0425 | cannot find value in this scope | A name is misspelled, or used outside the block where it lives |
| E0599 | no method named … found | The method doesn’t exist on that type, or its trait isn’t imported |
| E0384 | cannot assign twice to immutable variable | You changed a variable that wasn’t declared mut |
| E0596 | cannot borrow as mutable, as it is not declared as mutable | You tried to change something through a variable or reference that isn’t mut |
| E0597 | borrowed value does not live long enough | A reference is still in use after the value it points to is gone |
| E0515 | cannot return reference to local variable | You returned a reference to something that’s dropped when the function ends |
| E0373 | closure may outlive the current function, but it borrows … | A closure (often a thread) borrows a local that may be gone before it runs |
| E0369 | binary operation == cannot be applied to type … |
Your type doesn’t support ==, <, + and friends (yet) |
| E0432 | unresolved import | A use line points to a crate, module or item that can’t be found |
| E0433 | cannot find type … in this scope (older: failed to resolve) | A path like HashMap::new() uses a name that isn’t imported or doesn’t exist |
| E0424 | self value is a keyword only available in methods with a self parameter |
You used self in a function that doesn’t take self |
| E0061 | this function takes N arguments but M arguments were supplied | You passed too many or too few arguments (Rust has no optional arguments) |
| E0594 | cannot assign to p.hp, as p is not declared as mutable |
You changed a field or a value behind & without mut access |
| E0004 | non-exhaustive patterns: X not covered |
Your match doesn’t handle every possible value |
| E0507 | cannot move out of x which is behind a shared reference |
You tried to take ownership of something you only borrowed |
| E0603 | function x is private |
You used a function, struct or module that isn’t pub |
| E0716 | temporary value dropped while borrowed | You kept a reference to a value that’s thrown away at the end of the line |
| E0463 | can’t find crate for x |
A crate (or the standard library for a target) isn’t installed |
| E0368 | binary assignment operation += cannot be applied to type … |
Your type doesn’t support +=, -= and friends |
| E0057 | this function takes N arguments but M were supplied (note: closure defined here) | You called a closure with too many or too few arguments |
| E0282 | type annotations needed | Rust can’t work out a type on its own, so you need to say it |
| E0609 | no field x on type T |
The field name is misspelled, or the value is wrapped (e.g. in Option) |
| E0593 | closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments | A closure takes separate arguments where a tuple (or a different count) is expected |
| E0631 | type mismatch in closure arguments | A closure’s parameter type doesn’t match what it receives (often i32 vs &i32) |
| E0005 | refutable pattern in local binding | let Some(x) = … can fail, so plain let won’t accept it |
| E0615 | attempted to take value of method len on type String |
You wrote s.len instead of s.len() |
| E0610 | {integer} is a primitive type and therefore doesn’t have fields |
You used .field on a number, bool or char |
| E0560 | struct User has no field named nmae |
A struct literal uses a field name the struct doesn’t have |
| E0616 | field balance of struct Account is private |
You read a field that isn’t pub from outside its module |
| E0451 | field x of struct Y is private |
You built a struct with a literal while some of its fields are private |
| E0624 | method x is private |
You called a method or associated function that isn’t pub |
| E0283 | type annotations needed (cannot infer type … multiple impls satisfy this bound) | Several types could fit (e.g. .collect(), .sum()), so you have to choose one |
| E0284 | type annotations needed: cannot satisfy <_ as FromStr>::Err == _ |
"42".parse() doesn’t know which type to parse into |
| E0790 | cannot call associated function on trait without specifying the corresponding impl type |
You wrote Default::default() or Trait::new() without saying which type |
| E0559 | variant Shape::Circle has no field named r |
An enum variant literal uses a field name the variant doesn’t have |
| E0063 | missing field email in initializer of User |
You built a struct but left out one or more fields |
| E0689 | can’t call method pow on ambiguous numeric type {integer} |
2.pow(10) or 2.0.sqrt() needs a concrete number type like i32 or f64 |
| E0034 | multiple applicable items in scope | Two traits give your type a method with the same name, so Rust can’t pick one |
| E0412 | cannot find type X in this scope (Rust 1.93+ prints E0425) |
A type name is misspelled, not imported or not declared |
| E0428 | the name area is defined multiple times |
Two items share one name; Rust has no function overloading |
| E0026 | variant Shape::Circle does not have a field named r |
A pattern names a field the struct or variant doesn’t have |
| E0027 | pattern does not mention fields id, paid |
A struct pattern leaves out fields; add them or end with .. |
| E0533 | expected unit struct, unit variant or constant, found struct variant Shape::Circle |
A struct variant (or a function) is used where a plain name is expected; add { .. } |
| E0592 | duplicate definitions with name reset |
Two impl blocks define a method with the same name |
| E0255 | the name Error is defined multiple times |
A use import has the same name as your own type or function |
| E0252 | the name Result is defined multiple times |
Two use lines bring in the same name; rename one with as |
| E0411 | cannot find type Self in this scope |
You used Self outside an impl or trait |
| E0405 | cannot find trait Display in this scope |
A trait name is misspelled or not imported (e.g. use std::fmt::Display;) |
| E0532 | expected unit struct, unit variant or constant, found tuple variant Shape::Circle |
A pattern names a tuple variant (or struct) without its ( ), or adds ( ) where none belong |
| E0164 | expected tuple struct or tuple variant, found struct variant Shape::Circle |
A pattern uses ( ) on a struct variant or an associated item; use { } or a guard |
| E0404 | expected trait, found derive macro Debug |
You wrote impl X for or T: X where X is a struct, alias or un-imported derive macro |
| E0401 | can’t use generic parameters from outer item | An inner fn uses the outer function’s T or Self; give it its own generics or use a closure |
| E0107 | enum takes 2 generic arguments but 1 generic argument was supplied | Result<u32>, HashMap<String> and friends: too few or too many < > arguments |
| E0530 | match bindings cannot shadow tuple variants | A bare variant name like Circle => (after use Shape::*) can’t be a new variable |
| E0434 | can’t capture dynamic environment in a fn item | An inner fn can’t see outer local variables; use a closure or pass them in |
| E0601 | main function not found in crate main |
The binary has no fn main() (missing, misspelled, inside a mod, or it’s really a library) |
| E0658 | use of unstable library feature iter_intersperse |
You used a nightly-only API on stable Rust; use the stable alternative or update |
| E0614 | type u32 cannot be dereferenced |
You wrote *x where x is already a plain value, not a reference |
| E0435 | attempt to use a non-constant value in a constant | A const, array length or static uses a let variable; make it a const or use a Vec |
| E0554 | #![feature] may not be used on the stable release channel |
Copied nightly-only code; remove the attribute and use the stable API, or use nightly on purpose |
How to read a Rust error
Section titled “How to read a Rust error”Rust’s error messages are famously helpful, but they pack a lot in. Here’s a real one:
fn main() { let name = String::from("Ferris"); let greeting = name; println!("{name}");}error[E0382]: borrow of moved value: `name` --> src/main.rs:4:16 |2 | let name = String::from("Ferris"); | ---- move occurs because `name` has type `String`, which does not implement the `Copy` trait3 | let greeting = name; | ---- value moved here4 | println!("{name}"); | ^^^^ value borrowed here after move |help: consider cloning the value if the performance cost is acceptable |3 | let greeting = name.clone(); | ++++++++Read it in this order:
- The first line is the summary: the error code (
E0382) and a one-line description. - The arrow line (
--> src/main.rs:4:16) tells you the file, line and column where things went wrong. - The
^^^^marks point at the exact spot of the error. The----marks are the story leading up to it. Here they say: the value was created on line 2, moved on line 3, then used on line 4. help:is the compiler’s suggested fix, often with the exact code to add (the++++marks show new characters). It’s not always the best fix, but it’s a great starting point.
Start reading at the first error. One mistake can cause a chain of follow-up errors, and fixing the first one often makes the rest disappear.
Three habits that help
Section titled “Three habits that help”-
Ask the compiler for more. Every error code has a longer explanation built in. Run this in a terminal:
Terminal window rustc --explain E0382You’ll get a short description, a broken example and a fixed one.
-
Check often.
cargo checkfinds errors without building the whole program, so it’s much faster thancargo build. Running it after every few lines means you meet one error at a time, not twenty. See Cargo & Crates. -
Let your editor show errors as you type. With the rust-analyzer extension, errors appear right in your code, with the same help text. See Rust Tools & Setup.
Why Rust has so many errors
Section titled “Why Rust has so many errors”Most of these errors exist because Rust checks, before your program runs, things other languages only discover at runtime (or never): using freed memory, two threads changing the same data, a missing null check. Each error you fix is a bug that will never reach your users.
That’s why many people say: in Rust, the fight happens at compile time, and then the program just works. The rules behind the most common errors are covered in Ownership, Borrowing and Lifetimes.
Quick check
Section titled “Quick check”Quick check
1. A Rust error shows several problems. Which one should you fix first?
2. What does rustc --explain E0382 do?
3. In an error message, what do the ^^^^ marks show?
Score: 0 / 3
Read more
Section titled “Read more”- Rust Compiler Error Index: the official list of every error code, each with a broken and a fixed example.
- Understanding Ownership — The Rust Book: the rules behind the most common borrowing and moving errors.
- Error Handling — The Rust Book: how Rust handles errors in your own programs (
Resultandpanic!), not just compiler errors. - What is rustc? — The rustc Book: how the compiler works, including its flags and lint levels.