{"record":{"id":"37d23d9e67692667","repo":"microsoft/FASTER","slug":"allocator-with-sector-size-sectorsize-cannot-flush-to-device","errorCode":null,"errorMessage":"Allocator with sector size {sectorSize} cannot flush to device with sector size {device.SectorSize}","messagePattern":"Allocator with sector size (.+?) cannot flush to device with sector size (.+?)","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"critical","filePath":"cs/src/core/Allocator/AllocatorBase.cs","lineNumber":429,"sourceCode":"        /// <summary>\n        /// Write async to device\n        /// </summary>\n        /// <typeparam name=\"TContext\"></typeparam>\n        /// <param name=\"startPage\"></param>\n        /// <param name=\"flushPage\"></param>\n        /// <param name=\"pageSize\"></param>\n        /// <param name=\"callback\"></param>\n        /// <param name=\"result\"></param>\n        /// <param name=\"device\"></param>\n        /// <param name=\"objectLogDevice\"></param>\n        /// <param name=\"localSegmentOffsets\"></param>\n        /// <param name=\"fuzzyStartLogicalAddress\">Start address of fuzzy region, which contains old and new version records (we use this to selectively flush only old-version records during snapshot checkpoint)</param>\n        protected abstract void WriteAsyncToDevice<TContext>(long startPage, long flushPage, int pageSize, DeviceIOCompletionCallback callback, PageAsyncFlushResult<TContext> result, IDevice device, IDevice objectLogDevice, long[] localSegmentOffsets, long fuzzyStartLogicalAddress);\n\n        private protected void VerifyCompatibleSectorSize(IDevice device)\n        {\n            if (this.sectorSize % device.SectorSize != 0)\n                throw new FasterException($\"Allocator with sector size {sectorSize} cannot flush to device with sector size {device.SectorSize}\");\n        }\n\n        internal long GetReadOnlyLagAddress() => ReadOnlyLagAddress;\n\n        /// <summary>\n        /// Delta flush\n        /// </summary>\n        /// <param name=\"startAddress\"></param>\n        /// <param name=\"endAddress\"></param>\n        /// <param name=\"prevEndAddress\"></param>\n        /// <param name=\"version\"></param>\n        /// <param name=\"deltaLog\"></param>\n        /// <param name=\"completedSemaphore\"></param>\n        /// <param name=\"throttleCheckpointFlushDelayMs\"></param>\n        internal unsafe virtual void AsyncFlushDeltaToDevice(long startAddress, long endAddress, long prevEndAddress, long version, DeltaLog deltaLog, out SemaphoreSlim completedSemaphore, int throttleCheckpointFlushDelayMs)\n        {\n            logger?.LogTrace(\"Starting async delta log flush with throttling {throttlingEnabled}\", throttleCheckpointFlushDelayMs >= 0 ? $\"enabled ({throttleCheckpointFlushDelayMs}ms)\" : \"disabled\");\n","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Allocator/AllocatorBase.cs#L411-L447","documentation":"AllocatorBase.VerifyCompatibleSectorSize enforces that the allocator's sector size is an integer multiple of the flush device's sector size (allocatorSectorSize % deviceSectorSize == 0). FASTER aligns flushes to sector boundaries; flushing to a device with larger sectors than the allocator assumed would produce misaligned writes or data corruption, so it throws FasterException.","triggerScenarios":"Creating a hybrid log/device stack where the log's configured sector size (or a device's reported sector size) is smaller-grained than the target device — e.g. allocator sectorSize=512 while device.SectorSize=4096, attaching devices created with different sector settings, or a device emulation layer reporting a large sector size.","commonSituations":"Running on storage (or device emulation like local emulated devices) that reports 4K-native sectors while FASTER was configured with 512-byte sectors; moving checkpoints/logs between devices with different sector sizes; Windows/Linux differences in reported sector geometry.","solutions":["Configure the log's sector size to be a multiple of the device's sector size (e.g. pass sectorSize: 4096 when the device reports 4096).","Recreate the device with matching/explicit sector size parameters so allocator and device agree.","Move the log onto a device whose sector size divides the allocator's sector size (e.g. use a file/device emulation with 512-byte sectors)."],"exampleFix":"// before\nvar device = Devices.CreateLogDevice(path, sectorSize: 512); // device reports 4096\n// after\nvar device = Devices.CreateLogDevice(path, sectorSize: 4096); // matches allocator sector size","handlingStrategy":"validation","validationCode":"if (allocatorSectorSize % device.SectorSize != 0)\n    throw new InvalidOperationException($\"Set log sector size to a multiple of device sector size {device.SectorSize}\");","typeGuard":null,"tryCatchPattern":"try { store = new FasterKV<K,V>(...); } catch (FasterException) { /* recreate devices with sectorSize = device.SectorSize */ }","preventionTips":["Query device.SectorSize and pass it (or a multiple) as the log's sector size when creating devices.","Avoid moving logs between devices with different sector geometries without recreating the store."],"tags":["csharp","faster","storage","sector-size","device"],"backgroundTag":"incompatible-source-type","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}