{"record":{"id":"9cd586e1987a1d75","repo":"microsoft/garnet","slug":"aofpagesize-effective-effectiveaofpage-after-ro","errorCode":null,"errorMessage":"AofPageSize (effective {effectiveAofPage} after rounding down to a power of two) must be at least twice the main-log PageSize (effective {effectiveMainPage}). Increase --aof-page-size to at least {minAofPage} (and --aof-memory to at least {PrettySize(1L << (mainPageSizeBits + 2))}), or reduce --page.","messagePattern":"AofPageSize \\(effective (.+?) after rounding down to a power of two\\) must be at least twice the main-log PageSize \\(effective (.+?)\\)\\. Increase --aof-page-size to at least (.+?) \\(and --aof-memory to at least (.+?)\\), or reduce --page\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"libs/server/Servers/GarnetServerOptions.cs","lineNumber":1018,"sourceCode":"\n            // AofPageSize must be at least twice the main-log PageSize. An AOF entry mirrors a single\n            // main-log write (key + value/input + small overhead); raw-string SETs can be as large as\n            // the main-log PageSize (values above MaxInlineValueSize overflow to the heap on the main\n            // store but are still written in full to the AOF), and object commands like LPUSH/HSET can\n            // push the AOF entry even higher. Throw a clear error here so users do not hit the runtime\n            // \"Entry does not fit on page\" path with a stalled session.\n            var mainPageSizeBits = PageSizeBits();\n            if (pageSizeBits < mainPageSizeBits + 1)\n            {\n                var effectiveAofPage = PrettySize(1L << pageSizeBits);\n                var effectiveMainPage = PrettySize(1L << mainPageSizeBits);\n                var minAofPage = PrettySize(1L << (mainPageSizeBits + 1));\n                var msg = $\"AofPageSize (effective {effectiveAofPage} after rounding down to a power of two) \" +\n                          $\"must be at least twice the main-log PageSize (effective {effectiveMainPage}). \" +\n                          $\"Increase --aof-page-size to at least {minAofPage} (and --aof-memory to at least {PrettySize(1L << (mainPageSizeBits + 2))}), \" +\n                          $\"or reduce --page.\";\n                logger?.LogError(\"{msg}\", msg);\n                throw new Exception(msg);\n            }\n\n            tsavoriteLogSettings = new TsavoriteLogSettings[AofPhysicalSublogCount];\n            for (var i = 0; i < AofPhysicalSublogCount; i++)\n            {\n                tsavoriteLogSettings[i] = new TsavoriteLogSettings\n                {\n                    MemorySizeBits = memorySizeBits,\n                    PageSizeBits = pageSizeBits,\n                    SegmentSizeBits = segmentSizeBits,\n                    LogDevice = GetAofDevice(dbId, subLogIdx: AofPhysicalSublogCount == 1 ? -1 : i),\n                    TryRecoverLatest = false,\n                    FastCommitMode = true,\n                    AutoCommit = AofAutoCommit && (AofPhysicalSublogCount == 1),\n                    MutableFraction = 0.9,\n                    Epoch = null\n                };\n","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/server/Servers/GarnetServerOptions.cs#L1000-L1036","documentation":"Garnet requires the AOF page size to be at least twice the main log's page size. An AOF entry mirrors a main-log write (key + value + overhead), and raw-string SETs can fill an entire main-log page. If the AOF page is too small, the entry will not fit on a page at runtime, stalling the session. The check is pageSizeBits < mainPageSizeBits + 1.","triggerScenarios":"Calling GetAofSettings() when AofPageSizeBits() < PageSizeBits() + 1. Occurs when --aof-page-size is less than 2× --page. For example, --page 32m --aof-page-size 32m fails because AOF page must be at least 64m.","commonSituations":"Increasing the main log --page for throughput without raising --aof-page-size; disabling AOF page override to use a default that is smaller than a custom main page; upgrading from a version without this cross-constraint check.","solutions":["Increase --aof-page-size to at least twice the effective --page value, and ensure --aof-memory is at least 4× --page.","Reduce --page so the existing --aof-page-size satisfies the 2× constraint.","Remove --aof-page-size and --aof-memory overrides so Garnet computes compatible values from --page."],"exampleFix":"// before\n--page 32m --aof-page-size 32m\n\n// after\n--page 32m --aof-page-size 64m --aof-memory 128m","handlingStrategy":"validation","validationCode":"var mainPageBits = options.PageSizeBits();\nvar aofPageBits = options.AofPageSizeBits();\nif (aofPageBits < mainPageBits + 1)\n    throw new InvalidOperationException($\"AOF page ({1L << aofPageBits} bytes) must be >= 2x main page ({1L << mainPageBits} bytes).\");","typeGuard":null,"tryCatchPattern":"try { options.GetAofSettings(dbId, out var settings); }\ncatch (Exception ex) when (ex.Message.Contains(\"main-log PageSize\"))\n{ logger.LogError(\"AOF page must be 2x main page: {Msg}\", ex.Message); throw; }","preventionTips":["When raising --page, also raise --aof-page-size to at least double and --aof-memory to at least quadruple.","Use a config template where all size values are derived from a single base to prevent mismatches.","Run a pre-deployment config validator that checks all cross-store size constraints."],"tags":["aof","configuration","startup","page-size","garnet"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}