{"record":{"id":"cbdc7b934e8e230c","repo":"microsoft/garnet","slug":"index-size-indexmemorysize-should-not-be-less-th","errorCode":null,"errorMessage":"Index size {IndexMemorySize} should not be less than index max size {IndexMaxMemorySize}","messagePattern":"Index size (.+?) should not be less than index max size (.+?)","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"libs/server/Servers/GarnetServerOptions.cs","lineNumber":732,"sourceCode":"                if (kvSettings.PageCount < bufferSize)\n                {\n                    logger?.LogInformation(\"[Store] Warning: overriding specified PageCount of {kvSettingsPageCount} with next power of 2 page count {bufferSize}\", kvSettings.PageCount, bufferSize);\n                    kvSettings.PageCount = bufferSize;\n                }\n                logger?.LogInformation(\"[Store] There are {LogPages} log pages in memory, all of which will be used because there is no MemorySize limit\", PrettySize(bufferSize));\n                logger?.LogInformation(\"[Store] No log memory size limit will be enforced\");\n            }\n\n            kvSettings.SegmentSize = 1L << SegmentSizeBits(isObj: false);\n            kvSettings.ObjectLogSegmentSize = 1L << SegmentSizeBits(isObj: true);\n            logger?.LogInformation(\"[Store] Using disk segment size of {SegmentSize}\", PrettySize(kvSettings.SegmentSize));\n\n            logger?.LogInformation(\"[Store] Using hash index size of {IndexMemorySize} ({indexCacheLines} cache lines)\", PrettySize(kvSettings.IndexSize), PrettySize(indexCacheLines));\n            logger?.LogInformation(\"[Store] Hash index size is optimized for up to ~{distinctKeys} distinct keys\", PrettySize(indexCacheLines * 4L));\n\n            AdjustedIndexMaxCacheLines = IndexMaxMemorySize == string.Empty ? 0 : IndexSizeCachelines(\"hash index max size\", IndexMaxMemorySize);\n            if (AdjustedIndexMaxCacheLines != 0 && AdjustedIndexMaxCacheLines < indexCacheLines)\n                throw new Exception($\"Index size {IndexMemorySize} should not be less than index max size {IndexMaxMemorySize}\");\n\n            if (AdjustedIndexMaxCacheLines > 0)\n            {\n                logger?.LogInformation(\"[Store] Using hash index max size of {MaxSize}, ({CacheLines} cache lines)\", PrettySize(AdjustedIndexMaxCacheLines * 64L), PrettySize(AdjustedIndexMaxCacheLines));\n                logger?.LogInformation(\"[Store] Hash index max size is optimized for up to ~{distinctKeys} distinct keys\", PrettySize(AdjustedIndexMaxCacheLines * 4L));\n            }\n            logger?.LogInformation(\"[Store] Using log mutable percentage of {MutablePercent}%\", MutablePercent);\n\n            if (DeviceType == DeviceType.Default)\n                DeviceType = Devices.GetDefaultDeviceType();\n            DeviceFactoryCreator ??= new LocalStorageNamedDeviceFactoryCreator(\n                deviceType: DeviceType,\n                ioBackend: DeviceIoBackend,\n                numCompletionThreads: DeviceCompletionThreads,\n                throttleLimit: DeviceThrottleLimit > 0 ? DeviceThrottleLimit : null,\n                logger: logger);\n            if (DeviceType == DeviceType.Native && OperatingSystem.IsLinux())\n                logger?.LogInformation(\"Using device type {deviceType} (io-backend={ioBackend}, completion-threads={ct}, throttle-limit={tl})\", DeviceType, DeviceIoBackend, DeviceCompletionThreads, DeviceThrottleLimit > 0 ? DeviceThrottleLimit.ToString() : \"device-default\");","sourceCodeStart":714,"sourceCodeEnd":750,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/server/Servers/GarnetServerOptions.cs#L714-L750","documentation":"GetSettings enforces that the initial hash index size (IndexMemorySize) is not larger than the maximum growable index size (IndexMaxMemorySize). IndexMaxMemorySize is optional (empty means 'never grow'); if it is set, its cache-line count must be >= the initial index's cache lines, otherwise the max would be below the starting size, which is nonsensical. Both are rounded down to a power of two before comparison.","triggerScenarios":"Setting --index/-i (IndexMemorySize) larger than --index-max-size (IndexMaxMemorySize), e.g. --index 256m --index-max-size 128m. Thrown at GarnetServerOptions.cs:731-732.","commonSituations":"Copy-paste config errors; intending to set a 'max' that is actually smaller than the start; misunderstanding that IndexMaxMemorySize is a growth ceiling, not the initial allocation.","solutions":["Make --index-max-size >= --index (e.g. --index 128m --index-max-size 256m).","Omit --index-max-size entirely if you do not want the index to grow (empty = fixed initial size).","Double-check that both values are power-of-two friendly, since they are rounded down before comparison."],"exampleFix":"# before (fails: initial > max)\ngarnet-server --index 256m --index-max-size 128m\n\n# after\ngarnet-server --index 128m --index-max-size 256m","handlingStrategy":"validation","validationCode":"// If a max index size is configured, it must be >= the initial size\nif (!string.IsNullOrEmpty(options.IndexMaxMemorySize)) {\n    var init = PreviousPowerOf2(ParseSize(options.IndexMemorySize, out _));\n    var max  = PreviousPowerOf2(ParseSize(options.IndexMaxMemorySize, out _));\n    if (max < init) throw new InvalidOperationException(\"IndexMaxMemorySize must be >= IndexMemorySize\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only set --index-max-size when you want growth, and keep it >= --index.","Remember both values round down to a power of two before comparison."],"tags":["garnet","config","tsavorite","storage","dotnet"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}