microsoft/FASTER · critical · FasterException
Allocator with sector size
Error message
Allocator with sector size {sectorSize} cannot flush to device with sector size {device.SectorSize} What it means
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.
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).
Example fix
// before var device = Devices.CreateLogDevice(path, sectorSize: 512); // device reports 4096 // after var device = Devices.CreateLogDevice(path, sectorSize: 4096); // matches allocator sector size
Defensive patterns
Strategy: validation
Validate before calling
if (allocatorSectorSize % device.SectorSize != 0)
throw new InvalidOperationException($"Set log sector size to a multiple of device sector size {device.SectorSize}"); Try / catch
try { store = new FasterKV<K,V>(...); } catch (FasterException) { /* recreate devices with sectorSize = device.SectorSize */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Getting handle in disposed device
- Local memory device must have a capacity!
- Cannot use LocalStorageDevice from non-Windows OS platform…
- Out of order message within session
- Unexpected status of SubscribeKV
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/37d23d9e67692667.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/Allocator/AllocatorBase.cs:429
/// <summary>
/// Write async to device
/// </summary>
/// <typeparam name="TContext"></typeparam>
/// <param name="startPage"></param>
/// <param name="flushPage"></param>
/// <param name="pageSize"></param>
/// <param name="callback"></param>
/// <param name="result"></param>
/// <param name="device"></param>
/// <param name="objectLogDevice"></param>
/// <param name="localSegmentOffsets"></param>
/// <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>
protected abstract void WriteAsyncToDevice<TContext>(long startPage, long flushPage, int pageSize, DeviceIOCompletionCallback callback, PageAsyncFlushResult<TContext> result, IDevice device, IDevice objectLogDevice, long[] localSegmentOffsets, long fuzzyStartLogicalAddress);
private protected void VerifyCompatibleSectorSize(IDevice device)
{
if (this.sectorSize % device.SectorSize != 0)
throw new FasterException($"Allocator with sector size {sectorSize} cannot flush to device with sector size {device.SectorSize}");
}
internal long GetReadOnlyLagAddress() => ReadOnlyLagAddress;
/// <summary>
/// Delta flush
/// </summary>
/// <param name="startAddress"></param>
/// <param name="endAddress"></param>
/// <param name="prevEndAddress"></param>
/// <param name="version"></param>
/// <param name="deltaLog"></param>
/// <param name="completedSemaphore"></param>
/// <param name="throttleCheckpointFlushDelayMs"></param>
internal unsafe virtual void AsyncFlushDeltaToDevice(long startAddress, long endAddress, long prevEndAddress, long version, DeltaLog deltaLog, out SemaphoreSlim completedSemaphore, int throttleCheckpointFlushDelayMs)
{
logger?.LogTrace("Starting async delta log flush with throttling {throttlingEnabled}", throttleCheckpointFlushDelayMs >= 0 ? $"enabled ({throttleCheckpointFlushDelayMs}ms)" : "disabled");
View on GitHub (pinned to 321d872eab)