microsoft/garnet · error · GarnetException
Failed to acquire inProgress lock at {nameof(PreBatchKeyCons
Error message
Failed to acquire inProgress lock at {nameof(PreBatchKeyConsistentReadCallback)} What it means
Thrown by ReplicaReadSessionContext.PreBatchKeyConsistentReadCallback when TryReadLock() on the 'inProgress' lock fails. This is the pre-read initialization for a batch of keys: it checks the consistency-manager version and caches key hashes. The read lock cannot be acquired because a writer (Dispose) currently holds it.
Source
Thrown at libs/server/AOF/ReadConsistency/ReplicaReadSessionContext.cs:201
throw new GarnetException($"Failed to acquire inProgress lock at {nameof(PostSingleKeyConsistentReadCallback)}");
try
{
appendOnlyFile.readConsistencyManager.PostSingleKeyConsistentRead(ref replicaReadContext);
}
finally
{
inProgress.ReadUnlock();
}
}
/// <summary>
/// Initialize context for read key batch.
/// </summary>
/// <param name="parameters"></param>
public void PreBatchKeyConsistentReadCallback(ReadOnlySpan<PinnedSpanByte> parameters)
{
if (!inProgress.TryReadLock())
throw new GarnetException($"Failed to acquire inProgress lock at {nameof(PreBatchKeyConsistentReadCallback)}");
try
{
var keyCount = parameters.Length;
var consistencyManager = appendOnlyFile.readConsistencyManager;
// First check if version of consistency manager has changed
appendOnlyFile.readConsistencyManager.CheckConsistencyManagerVersion(ref replicaReadContext);
// Allocate array to cache key hashes for batch read
if (keyHashCache == null || keyCount > keyHashCache.Length)
ExpandKeyHashCache(keyCount);
else if ((keyCount << 2) < keyHashCache.Length)
ShrinkKeyHashCache(keyCount);
// NOTE: this context is a copy used to emulate standalone reads.
// The actual update of the session max will happen after the read succeeds.
batchReadContext = replicaReadContext;
for (var i = 0; i < parameters.Length; i++)
{View on GitHub (pinned to 951b0fc683)
Solutions
- Verify session liveness before issuing the batch read.
- Catch GarnetException and return an error to the client (e.g. session closed).
- Ensure dispose waits for all queued read callbacks to drain.
- Add a disposed-flag guard at the start of the batch-read entry point.
Example fix
// before
session.PreBatchKeyConsistentReadCallback(parameters);
// after
if (session.IsDisposed) return BatchReadResult.SessionClosed;
try { session.PreBatchKeyConsistentReadCallback(parameters); }
catch (GarnetException) { return BatchReadResult.SessionClosed; } Defensive patterns
Strategy: try-catch
Validate before calling
if (session.IsDisposed) return BatchReadResult.SessionClosed; session.PreBatchKeyConsistentReadCallback(parameters);
Try / catch
try { session.PreBatchKeyConsistentReadCallback(parameters); }
catch (GarnetException ex) when (ex.Message.Contains("inProgress lock"))
{ return BatchReadResult.SessionClosed; } Prevention
- Gate batch reads on session liveness.
- Drain queued read callbacks before session disposal.
- Correlate lock failures with dispose events in logs for diagnosis.
When it happens
Trigger: A batch consistent read is initiated on a session that is concurrently being disposed, or a write lock is held due to re-entrancy. The non-blocking TryReadLock returns false and the method throws.
Common situations: Connection close / session teardown racing with a batch read request; a cancellation path disposing the session while the batch read callback is queued; a bug calling the batch read on a disposed session.
Related errors
- Failed to acquire inProgress lock at {nameof(PostBatchKeyCon
- Failed to acquire inProgress lock at {nameof(PreSingleKeyCon
- Failed to acquire inProgress lock at {nameof(PostSingleKeyCo
- Type not supported {headerType}
- Unsupported header type: {headerType}
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/c913001faebffc8e.
Report an issue: GitHub.