microsoft/garnet · error · GarnetException

Setting bitfield failed: Size of bitmap smaller than offset

Error message

Setting bitfield failed: Size of bitmap smaller than offset provided.

What it means

Thrown by SetBitfield after offset validation passed but byteIndexStart >= bitmapLength - the bitmap buffer handed to the setter is shorter than the offset requires. For SET the bitmap is expected to be grown to cover the offset first; reaching this throw means the buffer was not grown (or the offset exceeds the allocated size). Distinct from the range-error throws: the offset itself is valid, the buffer is just too small.

Source

Thrown at libs/server/Resp/Bitmap/BitmapManagerBitfield.cs:371

        /// <param name="encoding"></param>
        /// <param name="signed"></param>
        /// <param name="newValue"></param>
        /// <param name="overflowType"></param>
        /// <returns></returns>
        /// <exception cref="GarnetException"></exception>
        private static (long, bool) SetBitfield(byte* bitmap, long bitmapLength, long offset, byte encoding, bool signed, long newValue, byte overflowType)
        {
            if (!TryValidateBitfieldOffset(offset, encoding, multiplyOffset: false, out offset, out var endOffset))
                throw new GarnetException("ERR value is not an integer or out of range.");

            var byteIndexStart = Index(offset);
            var byteIndexEnd = Index(endOffset) + 1;
            var buf = stackalloc byte[8];
            *(ulong*)buf = 0;

            // Simple case value is beyond current length
            if (byteIndexStart >= bitmapLength)
                throw new GarnetException("Setting bitfield failed: Size of bitmap smaller than offset provided.");

            #region getValue
            // Shift with typeInfo in mind            
            var vend = bitmap + bitmapLength;
            var curr = bitmap + byteIndexStart;
            var cend = bitmap + byteIndexEnd < vend ? (bitmap + byteIndexEnd) : vend;
            var oldValue = GetValue(ref buf, ref curr, cend, vend, bitmapLength, offset, encoding, signed);

            #endregion

            #region checkOverflow
            if (overflowType == (byte)BitFieldOverflow.FAIL && CheckBitfieldOverflow(oldValue, 0, out _, encoding, overflowType, signed))
                return (0, true);
            #endregion

            #region setValue
            // Prune leading bits
            var _left = (int)(offset - (byteIndexStart << 3));

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Ensure the bitmap is grown to Index(offset) + requiredBytes before calling SET (normally done by the command layer).
  2. If hitting memory limits, raise the configured bitmap/object size limit or reduce the offset.
  3. If reproducible on a current build with a normal SET, report it - the growth step may be missing.
Defensive patterns

Strategy: validation

Validate before calling

// Before SET, ensure the bitmap is large enough for the target offset
var neededBytes = (int)(offset >> 3) + EncodingByteLength(encoding);
if (currentBitmapLength < neededBytes)
    currentBitmap = GrowBitmap(currentBitmap, neededBytes);

Try / catch

catch (GarnetException ex) when (ex.Message.StartsWith("Setting bitfield failed: Size of bitmap")) {
    logger.LogError("Bitmap not grown for SET offset; check allocation path");
    throw;
}

Prevention

When it happens

Trigger: SetBitfield is called with a byte-index start at/over the provided bitmap length - the caller did not pre-grow the bitmap to cover the SET offset.

Common situations: An internal SET path that fails to grow the bitmap before invoking the setter; memory/allocation limits preventing growth; a very large offset on a small/empty bitmap where growth was skipped.

Related errors


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/83a31b17c95fe55c. Report an issue: GitHub.