microsoft/FASTER · error · FasterException

capacity must be a multiple of segment sizes

Error message

capacity must be a multiple of segment sizes

What it means

StorageDeviceBase.Initialize validates that when a finite segment size is used, the device's total Capacity must be an exact multiple of that segment size, since the address space is divided into fixed-size segments. A mismatch means the last segment would not fit, so construction is refused.

Solutions

  1. Set capacityLimit to a multiple of segmentSize (or 0/-1 for unlimited).
  2. Use power-of-two sizes and derive them from bits (e.g., capacity 2^30 with segmentSize 2^28).
  3. Pass segmentSize = -1 to disable the capacity-multiple requirement (unlimited capacity).
  4. Let device factory helpers (e.g., Devices.CreateLogDevice) compute consistent bits instead of setting raw values.

Example fix

// before
var device = new LocalStorageDevice(path, capacity: 1L << 30); // 1 GiB
...
device.Initialize(segmentSize: 3L << 30); // 3 GiB segment: 1 GiB % 3 GiB != 0
// after
device.Initialize(segmentSize: 1L << 28); // 256 MiB segments: 1 GiB is an exact multiple
Defensive patterns

Strategy: validation

Validate before calling

if (segmentSize != -1 && capacity != -1 && capacity % segmentSize != 0)
    throw new ArgumentException("capacity must be a multiple of segmentSize");

Try / catch

try { device.Initialize(segmentSize, epoch); } catch (FasterException e) when (e.Message.Contains("multiple of segment")) { /* fix capacity config */ }

Prevention

When it happens

Trigger: Calling Initialize(segmentSize, ...) (directly or via device setup where Capacity was set) with segmentSize != -1 and Capacity % segmentSize != 0 — e.g., Capacity=1GB with segmentSize=3GB, or a device created with capacityLimit that isn't divisible by the chosen segment size.

Common situations: Manually constructing LocalStorageDevice/ManagedLocalStorageDevice with a capacityLimit and custom segment size; switching logMemorySizeBits/segmentSizeBits combinations so bits no longer divide evenly; copy-pasted configuration where capacity was changed but segment size was not.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at cs/src/core/Device/StorageDeviceBase.cs:106

            segmentSize = -1;
            segmentSizeBits = 64;
            segmentSizeMask = ~0UL;

            Capacity = capacity;
        }

        /// <summary>
        /// Initialize device
        /// </summary>
        /// <param name="segmentSize"></param>
        /// <param name="epoch"></param>
        /// <param name="omitSegmentIdFromFilename"></param>
        public virtual void Initialize(long segmentSize, LightEpoch epoch = null, bool omitSegmentIdFromFilename = false)
        {
            if (segmentSize != -1)
            { 
                if (Capacity != -1 && Capacity % segmentSize != 0)
                    throw new FasterException("capacity must be a multiple of segment sizes");
                if (omitSegmentIdFromFilename)
                    throw new FasterException("omitSegmentIdInFilename requires a segment size of -1");
            }
            this.segmentSize = segmentSize;
            this.epoch = epoch;
            this.OmitSegmentIdFromFileName = omitSegmentIdFromFilename;
            if (!Utility.IsPowerOfTwo(segmentSize))
            {
                if (segmentSize != -1)
                    throw new FasterException("Invalid segment size: " + segmentSize);
                segmentSizeBits = 64;
                segmentSizeMask = ~0UL;
            }
            else
            {
                segmentSizeBits = Utility.GetLogBase2((ulong)segmentSize);
                segmentSizeMask = (ulong)segmentSize - 1;
            }

View on GitHub (pinned to 321d872eab)