microsoft/garnet · error · TsavoriteException
Segment ({SegmentSize}) must be at least of page size ({Page
Error message
Segment ({SegmentSize}) must be at least of page size ({PageSize}) What it means
Thrown in the segment-size step: SegmentSize (1 << SegmentSizeBits) must be >= PageSize (1 << PageSizeBits), because segments are groups of pages and cannot be smaller than a single page. Even when each of PageSizeBits and SegmentSizeBits is individually in range (errors 222 and 225), a large page combined with a smaller segment trips this; e.g. PageSizeBits=25 (32MiB) with SegmentSizeBits=12 (4KiB) => 4KiB < 32MiB.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/Allocator/AllocatorBase.cs:639
MaxAllocatedPageCount = logSettings.PageCount > 0 ? logSettings.PageCount : (int)(logSettings.MemorySize / PageSize);
}
else
{
if (logSettings.PageCount <= 0)
throw new TsavoriteException($"Log Memory size or PageCount must be specified");
MaxAllocatedPageCount = logSettings.PageCount;
}
BufferSize = (int)NextPowerOf2(MaxAllocatedPageCount);
BufferSizeMask = BufferSize - 1;
logMutableFraction = logSettings.MutableFraction;
// Segment size
LogSegmentSizeBits = logSettings.SegmentSizeBits;
SegmentSize = 1L << LogSegmentSizeBits;
if (SegmentSize < PageSize)
throw new TsavoriteException($"Segment ({SegmentSize}) must be at least of page size ({PageSize})");
PageStatusIndicator = new FullPageStatus[BufferSize];
if (!IsNullDevice)
{
PendingFlush = new PendingFlushList[BufferSize];
for (int i = 0; i < BufferSize; i++)
PendingFlush[i] = new PendingFlushList();
}
device = logSettings.LogDevice;
sectorSize = (int)device.SectorSize;
if (PageSize < sectorSize)
throw new TsavoriteException($"Page size must be at least of device sector size ({sectorSize} bytes). Set PageSizeBits accordingly.");
AlignedPageSizeBytes = RoundUp(PageSize, sectorSize);
if (BufferSize > 0)View on GitHub (pinned to 951b0fc683)
Solutions
- Ensure SegmentSizeBits >= PageSizeBits (so each segment holds at least one page).
- When raising PageSizeBits, raise SegmentSizeBits to match or exceed it.
- Keep the defaults (PageSizeBits=25, SegmentSizeBits=30) unless you have measured reason to change both consistently.
Example fix
// before logSettings.PageSizeBits = 25; // 32MiB page logSettings.SegmentSizeBits = 12; // 4KiB segment -> < page // after logSettings.SegmentSizeBits = 30; // 1GiB segment >= 32MiB page
Defensive patterns
Strategy: validation
Validate before calling
// Segment must be >= page: SegmentSizeBits >= PageSizeBits.
if (logSettings.SegmentSizeBits < logSettings.PageSizeBits)
logSettings.SegmentSizeBits = logSettings.PageSizeBits; // or larger, e.g. +5 Try / catch
try { new TsavoriteKV<K,V>(logSettings, ...); }
catch (TsavoriteException ex) when (ex.Message.Contains("Segment") && ex.Message.Contains("at least of page size"))
{ /* raise SegmentSizeBits to >= PageSizeBits and recreate */ } Prevention
- Always keep SegmentSizeBits >= PageSizeBits.
- When tuning PageSizeBits up, recheck SegmentSizeBits in the same change.
- Add a config assertion: SegmentSizeBits >= PageSizeBits.
When it happens
Trigger: Setting SegmentSizeBits < PageSizeBits, or raising PageSizeBits above the existing SegmentSizeBits without also raising the segment size.
Common situations: Tuning PageSizeBits up for fewer, larger flush units and forgetting to bump SegmentSizeBits; mirroring a config where the two were changed independently.
Related errors
- {nameof(logSettings.PageSizeBits)} must be between {LogSetti
- {nameof(logSettings.PageSizeBits)} must be >= PageHeader.Siz
- {nameof(logSettings.SegmentSizeBits)} must be between {LogSe
- {nameof(logSettings.MemorySize)} must be at least {LogSettin
- {nameof(rcs.PageSizeBits)} must be between {LogSettings.kMin
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/55db727e7e1a1ac3.
Report an issue: GitHub.