microsoft/FASTER · error · FasterException

BlittableAllocator memory pages are sector aligned - use…

Error message

BlittableAllocator memory pages are sector aligned - use direct copy

What it means

VarLenBlittableAllocator allocates its memory pages directly as sector-aligned device-sized buffers, so a read page already lands in its final memory location and there is nothing to 'populate' by copying. PopulatePage — used by allocators that copy device data into separately allocated memory pages — is therefore invalid and throws FasterException as a guard. The commented-out MemoryCopy shows the base-class behavior it intentionally disables.

Solutions

  1. Use the direct copy path: with VarLenBlittableAllocator, the sector-aligned device buffer is the page, so consume it in place instead of calling PopulatePage.
  2. If you need PopulatePage-style copying, switch to the standard BlittableAllocator (which stages pages) instead of VarLenBlittableAllocator.
  3. Update custom read/flush code to respect the allocator's sector-aligned page contract (disk read lands directly in the page).

Example fix

// before
allocator.PopulatePage(src, requiredBytes, destinationPage);
// after: for VarLenBlittableAllocator, use the device-read page directly
// (issue async read into the page buffer and consume it in place; no PopulatePage call)
Defensive patterns

Strategy: type-guard

Validate before calling

if (hlog is VarLenBlittableAllocator<K, V>) {
    // read directly into the sector-aligned page; skip PopulatePage entirely
}

Type guard

static bool NeedsPopulatePage(AllocatorBase<K, V> hlog)
    => hlog is not VarLenBlittableAllocator<K, V>;

Prevention

When it happens

Trigger: Invoking PopulatePage on a VarLenBlittableAllocator-backed log (hlog), typically from code or a generic path written for the standard BlittableAllocator/FasterBaseAllocator where pages must be copied from a device buffer. Reached via internal page-load logic or custom allocator-abusing code, not a normal user API.

Common situations: Porting scan/replay code that used PopulatePage with the default BlittableAllocator to the varlen blittable allocator; writing a custom device or read path that manually populates pages; mixing code samples across allocator types.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/07cc4186ac13a8af. Report an issue: GitHub.

Appendix: source

Thrown at cs/src/core/Allocator/VarLenBlittableAllocator.cs:494

        }

        /// <summary>
        /// Whether KVS has values to serialize/deserialize
        /// </summary>
        /// <returns></returns>
        public override bool ValueHasObjects()
        {
            return false;
        }

        public override long[] GetSegmentOffsets()
        {
            return null;
        }

        internal override void PopulatePage(byte* src, int required_bytes, long destinationPage)
        {
            throw new FasterException("BlittableAllocator memory pages are sector aligned - use direct copy");
            // Buffer.MemoryCopy(src, (void*)pointers[destinationPage % BufferSize], required_bytes, required_bytes);
        }

        /// <summary>
        /// Iterator interface for pull-scanning FASTER log
        /// </summary>
        public override IFasterScanIterator<Key, Value> Scan(FasterKV<Key, Value> store, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) 
            => new VariableLengthBlittableScanIterator<Key, Value>(store, this, beginAddress, endAddress, scanBufferingMode, epoch, logger: logger);

        /// <summary>
        /// Implementation for push-scanning FASTER log, called from LogAccessor
        /// </summary>
        internal override bool Scan<TScanFunctions>(FasterKV<Key, Value> store, long beginAddress, long endAddress, ref TScanFunctions scanFunctions, ScanBufferingMode scanBufferingMode)
        {
            using VariableLengthBlittableScanIterator<Key, Value> iter = new(store, this, beginAddress, endAddress, scanBufferingMode, epoch, logger: logger);
            return PushScanImpl(store, beginAddress, endAddress, ref scanFunctions, iter);
        }

View on GitHub (pinned to 321d872eab)