microsoft/FASTER · error · Exception

Local memory device must have a capacity!

Error message

Local memory device must have a capacity!

What it means

A LocalMemoryDevice is an in-memory device whose total size must be known upfront to allocate its RAM segments. FASTER's Devices.CAPACITY_UNSPECIFIED sentinel is not acceptable here, so the constructor rejects it.

Solutions

  1. Pass an explicit positive capacity, e.g. Devices.CreateLogDevice(path, capacity: 1L << 30).
  2. Compute capacity from expected log size (segment size * number of segments).
  3. If capacity is unknowable, use a disk/emulated device that supports unspecified capacity instead of a local memory device.

Example fix

// before
var device = Devices.CreateLogDevice("/userspace/ram/storage", capacity: Devices.CAPACITY_UNSPECIFIED);
// after
var device = Devices.CreateLogDevice("/userspace/ram/storage", capacity: 1L << 30); // 1 GiB
Defensive patterns

Strategy: validation

Validate before calling

if (capacity <= 0 || capacity == Devices.CAPACITY_UNSPECIFIED)
    throw new ArgumentException("LocalMemoryDevice requires an explicit positive capacity");

Prevention

When it happens

Trigger: Calling Devices.CreateLogDevice(path, capacity: Devices.CAPACITY_UNSPECIFIED) (or default/-1) such that LocalMemoryDevice is constructed with an unspecified capacity.

Common situations: Reusing storage-device configuration (capacity omitted) designed for disk devices when switching to in-memory devices; copying FASTER setup code between Kestrel/log setups where capacity was optional on emulated devices.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at cs/src/core/Device/LocalMemoryDevice.cs:56

        private readonly Thread[] ioProcessors;
        private readonly int parallelism;
        private readonly long sz_segment;
        private readonly long latencyTicks;
        private bool terminated;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="capacity">The maximum number of bytes this storage device can accommondate, or CAPACITY_UNSPECIFIED if there is no such limit </param>
        /// <param name="sz_segment">The size of each segment</param>
        /// <param name="parallelism">Number of IO processing threads</param>
        /// <param name="latencyMs">Induced callback latency in ms (for testing purposes)</param>
        /// <param name="sector_size">Sector size for device (default 64)</param>
        /// <param name="fileName">Virtual path for the device</param>
        public unsafe LocalMemoryDevice(long capacity, long sz_segment, int parallelism, int latencyMs = 0, uint sector_size = 64, string fileName = "/userspace/ram/storage")
            : base(fileName, sector_size, capacity)
        {
            if (capacity == Devices.CAPACITY_UNSPECIFIED) throw new Exception("Local memory device must have a capacity!");
            Debug.WriteLine("LocalMemoryDevice: Creating a " + capacity + " sized local memory device.");
            num_segments = (int)(capacity / sz_segment);
            this.sz_segment = sz_segment;
            this.latencyTicks = latencyMs * TimeSpan.TicksPerMillisecond;

            ram_segment_ptrs = new byte*[num_segments];
            orig_ram_segments = new byte[num_segments][];

#if !NET5_0_OR_GREATER
            ram_segment_handles = new GCHandle[num_segments];
#endif

            for (int i = 0; i < num_segments; i++)
            {
#if NET5_0_OR_GREATER
                orig_ram_segments[i] = GC.AllocateArray<byte>((int)sz_segment, true);
                ram_segment_ptrs[i] = (byte*)Unsafe.AsPointer(ref orig_ram_segments[i][0]);
#else

View on GitHub (pinned to 321d872eab)