Lock guard is still alive across an .await

ID

rust.correctness.await_holding_lock

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Concurrency

Language

Rust

Description

The guard returned by this lock is still in scope when the task suspends at the .await, so the lock stays held while another task runs and any task that needs it blocks — a deadlock if that task is what the awaited future is waiting for. Narrow the guard to its own block, or drop it before the .await.

Rationale

The guard returned by this lock is still in scope when the task suspends at the .await, so the lock stays held while another task runs and any task that needs it blocks — a deadlock if that task is what the awaited future is waiting for. Narrow the guard to its own block, or drop it before the .await.

The following code illustrates the pattern detected by this rule:

use std::sync::{Mutex, RwLock};
async fn persist(_value: u32) {}
pub async fn counter(state: &Mutex<u32>) {
    // FLAGGED: Lock guard is still alive across an `.await`
    let guard = state.lock().unwrap();
    persist(*guard).await;
    println!("{}", *guard);
}

Remediation

Follow secure coding practices and review the references below for detailed remediation guidance.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved