Safe Rust eliminates data races by design through its ownership and borrow checker system, making it impossible to have unsynchronized concurrent writes. However, Rust does not prevent race conditions in the broader sense. The post explains the precise difference: a data race requires concurrent access, at least one write, and no synchronization — all three at once — and is Undefined Behavior. Race conditions are logic bugs where outcomes depend on thread timing, such as TOCTOU (time-of-check-to-time-of-use) bugs, deadlocks, and lost updates. Concrete examples show how a bank account withdrawal can go negative even with correct mutex usage, how atomics don't solve the check-then-act problem, and how Rust's non-reentrant Mutex can deadlock. The key insight: Rust handles memory-level concurrency safety, but logical correctness of critical sections remains the developer's responsibility.