rustfs/rustfs · error · LockError
Invalid lock handle: {handle_id}
Error message
Invalid lock handle: {handle_id} What it means
A lock operation referenced a handle that the lock service does not recognize (handle id included). Locks are manipulated through handles issued at acquisition; this error means the handle is unknown — typically expired, already released, or evicted by the service.
Source
Thrown at crates/lock/src/error.rs:51
/// Network error
#[error("Network error: {message}")]
Network {
message: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
/// Internal error
#[error("Internal error: {message}")]
Internal { message: String },
/// Resource is already locked
#[error("Resource '{resource}' is already locked by {owner}")]
AlreadyLocked { resource: String, owner: String },
/// Invalid lock handle
#[error("Invalid lock handle: {handle_id}")]
InvalidHandle { handle_id: String },
/// Configuration error
#[error("Configuration error: {message}")]
Configuration { message: String },
/// Serialization error
#[error("Serialization error: {message}")]
Serialization {
message: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
/// Deserialization error
#[error("Deserialization error: {message}")]
Deserialization {
message: String,View on GitHub (pinned to 35af688cd9)
Solutions
- Drop the stale handle locally and re-acquire the lock if the work must continue
- Guard cleanup code so unlock is attempted exactly once per acquisition
- Enable/verify lease refresh for holds longer than the TTL so handles stay valid
Defensive patterns
Strategy: try-catch
Type guard
fn is_invalid_handle(e: &rustfs_lock::error::LockError) -> bool {
matches!(e, rustfs_lock::error::LockError::InvalidHandle { .. })
} Try / catch
match ns.unlock(handle.clone()).await {
Err(e) if is_invalid_handle(&e) => { /* already gone: drop local handle, not an error */ }
other => other?,
} Prevention
- Attempt unlock exactly once per acquired handle
- Refresh leases for holds longer than the TTL
- After a restart, re-acquire instead of reusing persisted handle ids
When it happens
Trigger: Calling unlock/refresh with a handle after the lock was already released; the lease expired and the service dropped the handle; process restarted and reused a persisted handle id that no longer exists.
Common situations: Double-unlock paths in cleanup code; long hold times exceeding lease TTL without refresh; failover invalidating outstanding handles.
Related errors
- Lock acquisition timeout for resource '{resource}' after {ti
- Resource not found: {resource}
- Permission denied: {reason}
- Network error: {message}
- Internal error: {message}
AI-assisted analysis of rustfs/rustfs@35af688cd9 (2026-08-20).
Data as JSON: /api/errors/c89d1ace733384d1.
Report an issue: GitHub.