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

  1. Use ReadAtAddress on session.BasicContext or session.TransactionalContext instead, which support address-based reads.
  2. If you need address-based reads with consistent reads, you cannot combine them in one context — use two separate contexts.
  3. 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

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


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/c5d5a0a986c058ea. Report an issue: GitHub.