microsoft/garnet · error · TsavoriteException

{nameof(logSettings.MaxInlineValueSize)} must be between {Lo

Error message

{nameof(logSettings.MaxInlineValueSize)} must be between {LogSettings.MinMaxInlineSize} and {LogSettings.MaxInlineValueSizeLimit}

What it means

Constructor validation: logSettings.MaxInlineValueSize must be in [MinMaxInlineSize, MaxInlineValueSizeLimit] = [0, (1<<RecordDataHeader.kValueLengthBits)-2] = [0, 16,777,214]. Values up to this many bytes are stored inline in the SpanByteAllocator in-memory record; larger values overflow. The upper limit is dictated by the 24-bit ValueLength field of RecordDataHeader. Default is 4096.

Source

Thrown at libs/storage/Tsavorite/cs/src/core/Allocator/AllocatorBase.cs:583

                var rcs = logSettings.ReadCacheSettings;
                if (rcs.PageCount == 0 && rcs.MemorySize == 0)
                    throw new TsavoriteException($"{nameof(rcs.PageCount)} or {nameof(rcs.MemorySize)} must be specified");
                if (rcs.PageSizeBits < LogSettings.kMinPageSizeBits || rcs.PageSizeBits > LogSettings.kMaxPageSizeBits)
                    throw new TsavoriteException($"{nameof(rcs.PageSizeBits)} must be between {LogSettings.kMinPageSizeBits} and {LogSettings.kMaxPageSizeBits}");
                if (rcs.PageCount > MemoryUtils.ArrayMaxLength)
                    throw new TsavoriteException($"{nameof(rcs.PageCount)} must be less than or equal to the maximum array length ({MemoryUtils.ArrayMaxLength})");
                if (rcs.MemorySize != 0 && (rcs.MemorySize < 1L << LogSettings.kMinMemorySizeBits || rcs.MemorySize > 1L << LogSettings.kMaxMemorySizeBits))
                    throw new TsavoriteException($"{nameof(rcs.MemorySize)} must be between {1L << LogSettings.kMinMemorySizeBits} and {1L << LogSettings.kMaxMemorySizeBits}");
                if ((rcs.MemorySize != 0) && (rcs.MemorySize < (1L << rcs.PageSizeBits) * 2))
                    throw new TsavoriteException($"{nameof(logSettings.MemorySize)} must be at least twice the page size ({1L << rcs.PageSizeBits})");
                if (rcs.SecondChanceFraction < 0.0 || rcs.SecondChanceFraction > 1.0)
                    throw new TsavoriteException($"{rcs.SecondChanceFraction} must be >= 0.0 and <= 1.0");
            }

            if (logSettings.MaxInlineKeySize < LogSettings.MinMaxInlineSize || logSettings.MaxInlineKeySize > LogSettings.MaxInlineKeySizeLimit)
                throw new TsavoriteException($"{nameof(logSettings.MaxInlineKeySize)} must be between {LogSettings.MinMaxInlineSize} and {LogSettings.MaxInlineKeySizeLimit}");
            if (logSettings.MaxInlineValueSize < LogSettings.MinMaxInlineSize || logSettings.MaxInlineValueSize > LogSettings.MaxInlineValueSizeLimit)
                throw new TsavoriteException($"{nameof(logSettings.MaxInlineValueSize)} must be between {LogSettings.MinMaxInlineSize} and {LogSettings.MaxInlineValueSizeLimit}");

            this.logger = logger;
            if (logSettings.LogDevice == null)
                throw new TsavoriteException("LogSettings.LogDevice needs to be specified (e.g., use Devices.CreateLogDevice, AzureStorageDevice, or NullDevice)");

            EvictCallback = evictCallback;

            FlushCallback = flushCallback;
            PreallocateLog = logSettings.PreallocateLog;
            flushEvent.Initialize();

            IsNullDevice = logSettings.LogDevice is NullDevice;

            if (epoch == null)
            {
                this.epoch = new LightEpoch();
                isEpochOwned = true;
            }

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Keep MaxInlineValueSize within [0, 16,777,214]; default 4096 is typical.
  2. For larger values, let them overflow rather than raising the inline ceiling.
  3. 0 is valid for a pure object store.

Example fix

// before
logSettings.MaxInlineValueSize = 1 << 25;  // 33MiB -> exceeds 24-bit field
// after
logSettings.MaxInlineValueSize = (1 << 24) - 2; // 16,777,214 max
Defensive patterns

Strategy: validation

Validate before calling

const int MaxInlineValue = (1 << 24) - 2; // MaxInlineValueSizeLimit = 16,777,214 (24-bit ValueLength field)
if (logSettings.MaxInlineValueSize < 0 || logSettings.MaxInlineValueSize > MaxInlineValue)
    logSettings.MaxInlineValueSize = Math.Clamp(logSettings.MaxInlineValueSize, 0, MaxInlineValue);

Try / catch

try { new TsavoriteKV<K,V>(logSettings, ...); }
catch (TsavoriteException ex) when (ex.Message.Contains("MaxInlineValueSize"))
{ /* clamp to [0,16,777,214]; let larger values overflow */ }

Prevention

When it happens

Trigger: Setting MaxInlineValueSize above 16,777,214 (~16MiB) or below 0.

Common situations: Raising inline value size to avoid overflow for large blobs and overshooting the 24-bit field; negative from a config sentinel.

Related errors


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