microsoft/garnet · error · TsavoriteException
Transactional consistent read context does not allow reads f
Error message
Transactional consistent read context does not allow reads from address!
What it means
TransactionalConsistentReadContext combines transactional locking with consistent-read snapshot isolation. ReadAtAddress bypasses the hash-based read path and reads directly from a log address, which would violate the consistent-read protocol (Pre/PostSingleKeyConsistentRead callbacks that maintain snapshot consistency). Therefore both ReadAtAddress overloads throw unconditionally. Only the hash-based Read methods are supported.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/ClientSession/TransactionalConsistentReadContext.cs:183
TOutput output = default;
return (Read(key, ref input, ref output, ref readOptions, userContext), output);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Status Read(TKey key, ref TInput input, ref TOutput output, ref ReadOptions readOptions, out RecordMetadata recordMetadata, TContext userContext = default)
{
var hash = readOptions.KeyHash ?? GetKeyHash(key);
Session.functions.PreSingleKeyConsistentRead(hash);
var status = TransactionalContext.Read(key, ref input, ref output, ref readOptions, out recordMetadata, userContext);
Session.functions.PostSingleKeyConsistentReadCallback();
return status;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Status ReadAtAddress(long address, ref TInput input, ref TOutput output, ref ReadOptions readOptions, out RecordMetadata recordMetadata, TContext userContext = default)
=> throw new TsavoriteException("Transactional consistent read context does not allow reads from address!");
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Status ReadAtAddress(long address, TKey key, ref TInput input, ref TOutput output, ref ReadOptions readOptions, out RecordMetadata recordMetadata, TContext userContext = default)
=> throw new TsavoriteException("Transactional consistent read context does not allow reads from address!");
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadWithPrefetch<TBatch>(ref TBatch batch, TContext userContext = default)
where TBatch : IReadArgBatch<TKey, TInput, TOutput>
#if NET9_0_OR_GREATER
, allows ref struct
#endif
{
do
{
Thread.Yield();
Session.functions.PreBatchKeyConsistentReadCallback(batch.Parameters);View on GitHub (pinned to 951b0fc683)
Solutions
- Use ReadAtAddress on session.BasicContext or session.TransactionalContext instead, which support address-based reads.
- If you need address-based reads with consistent reads, you cannot combine them in one context — use two separate contexts.
- If you only have the key (not the address), use Read(key, ...) on TransactionalConsistentReadContext instead of ReadAtAddress.
Example fix
// before (throws) session.TransactionalConsistentReadContext.ReadAtAddress(address, ref input, ref output, ref readOptions, out metadata); // after session.TransactionalContext.ReadAtAddress(address, ref input, ref output, ref readOptions, out metadata);
Defensive patterns
Strategy: validation
Validate before calling
// Use a context that supports address-based reads // TransactionalConsistentReadContext only supports hash-based reads session.TransactionalContext.ReadAtAddress(address, ref input, ref output, ref readOptions, out metadata);
Prevention
- Understand that consistent-read contexts enforce hash-based reads for snapshot isolation; address-based reads bypass that protocol.
- If you need address-based reads, use TransactionalContext or BasicContext, not the consistent-read variants.
- Keep record addresses for address-based reads on a separate context from consistent reads.
When it happens
Trigger: Calling ReadAtAddress(long address, ...) or ReadAtAddress(long address, TKey key, ...) on the session.TransactionalConsistentReadContext struct. This happens when a developer has a log address (e.g. from a RecordMetadata) and tries to read by address through the transactional consistent-read context.
Common situations: Replay or audit code that stores record addresses and tries to re-read them; migrating from BasicContext.ReadAtAddress to the transactional consistent-read context without realizing address-based reads are incompatible with consistent reads.
Related errors
- Consistent read context does not allow writes!
- Transactional consistent read context does not allow writes!
- Consistent read context does not allow writes!
- Consistent read context does not reset ResetModified!
- Consistent read context does not allow reads from address!
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/c5d5a0a986c058ea.
Report an issue: GitHub.