error[E0382]: borrow of moved value

Quick answer

You used a value after its ownership moved — it was assigned away, passed to a function by value, or returned. For a non-Copy type that invalidates the original binding. Fix it by borrowing (&value) instead of moving, deriving Copy for small types, or clone()ing only when both sides truly need ownership.

The exact error string

error[E0382]: borrow of moved value: `s`
 --> src/main.rs:4:20
  |
2 |     let s = String::from("hi");
  |         - move occurs because `s` has type `String`,
  |           which does not implement the `Copy` trait
3 |     let t = s;        // value moved here
  |             -
4 |     println!("{}", s); // value borrowed here after move
  |                    ^ value borrowed here after move

How to read it

Rust gives you three coordinates: "move occurs because ..." (the type isn't Copy), "value moved here" (the line that took ownership), and "value borrowed here after move" (the now-illegal use). The fix is almost always at that third line — make it borrow rather than consume.

Cause 1: moved by assignment, then used

let s = String::from("hi");
let t = s;              // ❌ s moved into t
println!("{} {}", s, t);

// ✅ borrow if you only need to read both
let s = String::from("hi");
let t = &s;            // t borrows, s still owns
println!("{} {}", s, t);

Cause 2: moved into a function, then used

fn show(v: Vec<i32>) { println!("{:?}", v); }

let nums = vec![1, 2, 3];
show(nums);            // ❌ nums moved into show()
println!("{}", nums.len());

// ✅ take a reference instead of ownership
fn show(v: &[i32]) { println!("{:?}", v); }
show(&nums);
println!("{}", nums.len());

Cause 3: moved by a for loop or closure

let words = vec![String::from("a"), String::from("b")];
for w in words { println!("{}", w); }  // moves & consumes words
println!("{}", words.len());           // ❌ value borrowed after move

// ✅ iterate by reference
for w in &words { println!("{}", w); }
println!("{}", words.len());           // words still owned

When clone or Copy is the right answer

// Small, cheap, value-semantics type -> derive Copy
#[derive(Clone, Copy)]
struct Point { x: i32, y: i32 }

// Both sides genuinely need an owned String -> clone explicitly
let s = String::from("hi");
let t = s.clone();     // deliberate deep copy
println!("{} {}", s, t);

Common causes at a glance

What moved the valueSymptomFix
let t = s;used s afterwardlet t = &s;
f(s) by valueused s after the calltake &s / &mut s
for x in vecvec unusable after loopfor x in &vec
move closurecaptured value gonecapture by reference
returning a fieldpartial move of a structreturn a clone or restructure

Debugging checklist

Frequently Asked Questions

What does 'borrow of moved value' (E0382) mean?

You used a value after its ownership was moved elsewhere — by assigning it, passing it to a function by value, or returning it. Once a non-Copy value moves, the original binding is invalid, so any later use is rejected at compile time.

What is the difference between move and borrow?

A move transfers ownership: the source can no longer be used. A borrow (&value or &mut value) lends temporary access without transferring ownership, so the original stays usable afterward. Most E0382 fixes are about borrowing instead of moving.

Should I just call .clone() to fix E0382?

clone() works and is sometimes the right call, but it copies the whole value at runtime. Prefer a borrow (&) when the callee only needs to read. Reach for clone only when both sides genuinely need to own a copy.

Why don't integers cause E0382?

Types that implement the Copy trait (integers, floats, bool, char, and tuples/arrays of them) are bit-copied instead of moved, so the original stays valid. String, Vec, Box, and most structs are not Copy, so they move.

Why does moving happen inside a loop or closure?

A for loop over a Vec by value moves each element (and consumes the Vec). A closure that captures a value by move (or a move closure) takes ownership. Iterate with &vec / vec.iter(), or capture by reference, to avoid the move.

How do I read the E0382 message?

Rust points at three spots: where the value was moved ("value moved here"), why the type can't Copy ("move occurs because ... does not implement the Copy trait"), and where you used it afterward ("value borrowed here after move"). Fix the middle use so it borrows.

More language & runtime errors

Browse the full reference for Rust, Go, Node.js, Python, and database errors — exact message, cause, and fix.

All Error References Rust: E0499 cannot borrow as mutable
About the author

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