E0499
Rust Programming Language
Severity: ModerateWhat Does This Error Mean?
Rust error E0499 means you have two active mutable borrows of the same value at the same time. Rust's borrow checker enforces a strict rule: you can have either one mutable reference OR any number of immutable references — never both, and never two mutables simultaneously. This rule eliminates a whole class of bugs (data races, iterator invalidation) at compile time. The fix is to ensure only one mutable borrow is active at any point, typically by ending the first borrow before creating the second.
Affected Models
- Rust 1.70+
- Rust 1.80+
- cargo build
- rustc compiler
- Any Rust project
Common Causes
- Two &mut references to the same variable are alive at the same time in the same scope
- A mutable reference is passed to a function while another mutable reference to the same value is still held
- A loop borrows a collection mutably while still holding a mutable reference from a previous iteration
- Calling a method that takes &mut self while another &mut reference to self exists
- A mutable reference is stored in a struct or variable and a second mutable borrow is attempted before the first is dropped
How to Fix It
-
Identify where the two mutable borrows begin and end. Rust's error message shows both borrow locations. The first borrow starts at one point — it must end (go out of scope) before the second can begin.
In Rust, a borrow ends when the variable holding it goes out of scope OR when the variable is last used (non-lexical lifetimes in Rust 2018+).
-
Drop the first mutable reference before creating the second. Add a scope block {} around the first borrow, or ensure the first reference is no longer used before you create the second one.
Example: { let a = &mut vec[0]; *a = 5; } let b = &mut vec[1]; — a is dropped when the block ends.
-
Use split_at_mut() when you need mutable references to two different parts of a slice simultaneously. split_at_mut() returns two non-overlapping mutable slices from one original slice.
Example: let (left, right) = slice.split_at_mut(mid); — left and right are separate mutable references to non-overlapping parts.
-
Use index-based access instead of holding multiple references. Instead of keeping two &mut references, work with indices: modify vec[0] and vec[1] directly one at a time.
Indices do not have lifetimes — they are just numbers. You can calculate both indices first, then perform mutations sequentially.
-
Consider using RefCell<T> for interior mutability if you need multiple mutable borrows at runtime. RefCell enforces borrow rules at runtime instead of compile time, allowing multiple borrows through checked borrowing.
RefCell panics at runtime if you violate borrow rules, instead of producing a compile error. Use it only when compile-time checking is too restrictive for your design.
When to Call a Professional
E0499 is a Rust borrow checker error — no external service is needed. The fix involves restructuring your code so that only one mutable borrow is active at a time. This is a fundamental Rust ownership concept that eliminates data races and mutation bugs at compile time.
Frequently Asked Questions
Why does Rust only allow one mutable reference at a time?
Two mutable references to the same data would allow aliased mutation — modifying data through one reference while another reference expects the data to be stable. This is the root cause of many bugs in C and C++: iterator invalidation (modifying a collection while iterating it), data races in multithreaded code, and use-after-free vulnerabilities. By enforcing one mutable borrow at a time, Rust eliminates these bugs entirely at compile time — with zero runtime cost.
What is the difference between E0499 and E0502?
E0499 is about two simultaneous mutable borrows of the same value. E0502 is about trying to borrow something as mutable while it is already borrowed as immutable (or vice versa). Both enforce Rust's core rule: you cannot have a mutable borrow active at the same time as any other borrow of the same value.
Does Rust 2018's non-lexical lifetimes help with E0499?
Yes — non-lexical lifetimes (NLL), introduced in Rust 2018, improved the borrow checker to end borrows at the last point they are used rather than at the end of their enclosing block. This resolved many false positive E0499 errors that existed in Rust 2015 edition. If you are using Rust 2015 edition, upgrading to Rust 2018 or 2021 in your Cargo.toml may resolve E0499 errors without code changes.