{"record":{"id":"a0921d1f4ae33161","repo":"microsoft/garnet","slug":"nameof-rcs-pagecount-or-nameof-rcs-memorysize","errorCode":null,"errorMessage":"{nameof(rcs.PageCount)} or {nameof(rcs.MemorySize)} must be specified","messagePattern":"(.+?) or (.+?) must be specified","errorType":"exception","errorClass":"TsavoriteException","httpStatus":null,"severity":"error","filePath":"libs/storage/Tsavorite/cs/src/core/Allocator/AllocatorBase.cs","lineNumber":567,"sourceCode":"            if (logSettings.PageSizeBits < LogSettings.kMinPageSizeBits || logSettings.PageSizeBits > LogSettings.kMaxPageSizeBits)\n                throw new TsavoriteException($\"{nameof(logSettings.PageSizeBits)} must be between {LogSettings.kMinPageSizeBits} and {LogSettings.kMaxPageSizeBits}\");\n            if (logSettings.PageSizeBits < PageHeader.SizeBits)\n                throw new TsavoriteException($\"{nameof(logSettings.PageSizeBits)} must be >= PageHeader.SizeBits {PageHeader.SizeBits}\");\n            if (logSettings.PageCount > MemoryUtils.ArrayMaxLength)\n                throw new TsavoriteException($\"{nameof(logSettings.PageCount)} must be less than or equal to the maximum array length ({MemoryUtils.ArrayMaxLength})\");\n            if (logSettings.SegmentSizeBits < LogSettings.kMinMainLogSegmentSizeBits || logSettings.SegmentSizeBits > LogSettings.kMaxSegmentSizeBits)\n                throw new TsavoriteException($\"{nameof(logSettings.SegmentSizeBits)} must be between {LogSettings.kMinMainLogSegmentSizeBits} and {LogSettings.kMaxSegmentSizeBits}\");\n            if (logSettings.MemorySize != 0 && (logSettings.MemorySize < 1L << LogSettings.kMinMemorySizeBits || logSettings.MemorySize > 1L << LogSettings.kMaxMemorySizeBits))\n                throw new TsavoriteException($\"{nameof(logSettings.MemorySize)} must be between {1L << LogSettings.kMinMemorySizeBits} and {1L << LogSettings.kMaxMemorySizeBits}, or may be 0 for ReadOnly TsavoriteLog\");\n            if ((logSettings.MemorySize != 0) && (logSettings.MemorySize < (1L << logSettings.PageSizeBits) * LogSettings.kMinPageCount))\n                throw new TsavoriteException($\"{nameof(logSettings.MemorySize)} must be at least {LogSettings.kMinPageCount}x the page size ({1L << logSettings.PageSizeBits})\");\n            if (logSettings.MutableFraction < 0.0 || logSettings.MutableFraction > 1.0)\n                throw new TsavoriteException($\"{nameof(logSettings.MutableFraction)} must be >= 0.0 and <= 1.0\");\n            if (logSettings.ReadCacheSettings is not null)\n            {\n                var rcs = logSettings.ReadCacheSettings;\n                if (rcs.PageCount == 0 && rcs.MemorySize == 0)\n                    throw new TsavoriteException($\"{nameof(rcs.PageCount)} or {nameof(rcs.MemorySize)} must be specified\");\n                if (rcs.PageSizeBits < LogSettings.kMinPageSizeBits || rcs.PageSizeBits > LogSettings.kMaxPageSizeBits)\n                    throw new TsavoriteException($\"{nameof(rcs.PageSizeBits)} must be between {LogSettings.kMinPageSizeBits} and {LogSettings.kMaxPageSizeBits}\");\n                if (rcs.PageCount > MemoryUtils.ArrayMaxLength)\n                    throw new TsavoriteException($\"{nameof(rcs.PageCount)} must be less than or equal to the maximum array length ({MemoryUtils.ArrayMaxLength})\");\n                if (rcs.MemorySize != 0 && (rcs.MemorySize < 1L << LogSettings.kMinMemorySizeBits || rcs.MemorySize > 1L << LogSettings.kMaxMemorySizeBits))\n                    throw new TsavoriteException($\"{nameof(rcs.MemorySize)} must be between {1L << LogSettings.kMinMemorySizeBits} and {1L << LogSettings.kMaxMemorySizeBits}\");\n                if ((rcs.MemorySize != 0) && (rcs.MemorySize < (1L << rcs.PageSizeBits) * 2))\n                    throw new TsavoriteException($\"{nameof(logSettings.MemorySize)} must be at least twice the page size ({1L << rcs.PageSizeBits})\");\n                if (rcs.SecondChanceFraction < 0.0 || rcs.SecondChanceFraction > 1.0)\n                    throw new TsavoriteException($\"{rcs.SecondChanceFraction} must be >= 0.0 and <= 1.0\");\n            }\n\n            if (logSettings.MaxInlineKeySize < LogSettings.MinMaxInlineSize || logSettings.MaxInlineKeySize > LogSettings.MaxInlineKeySizeLimit)\n                throw new TsavoriteException($\"{nameof(logSettings.MaxInlineKeySize)} must be between {LogSettings.MinMaxInlineSize} and {LogSettings.MaxInlineKeySizeLimit}\");\n            if (logSettings.MaxInlineValueSize < LogSettings.MinMaxInlineSize || logSettings.MaxInlineValueSize > LogSettings.MaxInlineValueSizeLimit)\n                throw new TsavoriteException($\"{nameof(logSettings.MaxInlineValueSize)} must be between {LogSettings.MinMaxInlineSize} and {LogSettings.MaxInlineValueSizeLimit}\");\n\n            this.logger = logger;","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/storage/Tsavorite/cs/src/core/Allocator/AllocatorBase.cs#L549-L585","documentation":"Constructor validation for the optional read cache: when logSettings.ReadCacheSettings is non-null, you must size it by setting at least one of rcs.PageCount or rcs.MemorySize (both default to 0). The read cache needs a resident page budget just like the main log.","triggerScenarios":"Enabling the read cache via `logSettings.ReadCacheSettings = new ReadCacheSettings()` and leaving both PageCount and MemorySize at their defaults (0).","commonSituations":"Turning on ReadCacheSettings to improve read hit rate but forgetting to size it; copying an example that omitted sizing fields.","solutions":["Set rcs.MemorySize to a positive value (e.g. 64MiB), or","Set rcs.PageCount to a positive number of pages.","If you did not intend a read cache, leave ReadCacheSettings = null."],"exampleFix":"// before\nlogSettings.ReadCacheSettings = new ReadCacheSettings();  // both size fields 0\n// after\nlogSettings.ReadCacheSettings = new ReadCacheSettings { MemorySize = 1L << 26 }; // 64MiB","handlingStrategy":"validation","validationCode":"if (logSettings.ReadCacheSettings is { } rcs && rcs.PageCount == 0 && rcs.MemorySize == 0)\n    throw new ArgumentException(\"ReadCacheSettings enabled but PageCount and MemorySize are both 0; set one.\");","typeGuard":null,"tryCatchPattern":"try { new TsavoriteKV<K,V>(logSettings, ...); }\ncatch (TsavoriteException ex) when (ex.Message.Contains(\"rcs.PageCount\") && ex.Message.Contains(\"must be specified\"))\n{ /* size the read cache via MemorySize or PageCount, then recreate */ }","preventionTips":["When enabling ReadCacheSettings, always set MemorySize (e.g. 64MiB) or PageCount.","Leave ReadCacheSettings=null if you do not need a read cache.","Centralize read-cache config so sizing is never omitted."],"tags":["storage","configuration","log-settings","read-cache"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}