microsoft/garnet · error · GarnetException
ERR bit offset is not an integer or out of range
Error message
ERR bit offset is not an integer or out of range
What it means
During BITFIELD command processing in the main store, Garnet validates the bit offset. TryValidateBitfieldOffset fails when: bitCount is 0, the offset is negative, the offset multiplication (for # syntax) overflows int64, the end offset (offset + bitCount - 1) overflows, or the end offset exceeds the maximum bitmap size. This mirrors Redis's 'ERR bit offset is not an integer or out of range' behavior.
Source
Thrown at libs/server/Storage/Functions/MainStore/PrivateMethods.cs:871
var cmd = RespCommand.NONE;
var sbCmd = input.parseState.GetArgSliceByRef(currTokenIdx++).ReadOnlySpan;
if (sbCmd.EqualsUpperCaseSpanIgnoringCase(CmdStrings.GET))
cmd = RespCommand.GET;
else if (sbCmd.EqualsUpperCaseSpanIgnoringCase(CmdStrings.SET))
cmd = RespCommand.SET;
else if (sbCmd.EqualsUpperCaseSpanIgnoringCase(CmdStrings.INCRBY))
cmd = RespCommand.INCRBY;
var bitfieldEncodingParsed = input.parseState.TryGetBitfieldEncoding(
currTokenIdx++, out var bitCount, out var isSigned);
Debug.Assert(bitfieldEncodingParsed);
var sign = isSigned ? (byte)BitFieldSign.SIGNED : (byte)BitFieldSign.UNSIGNED;
// Calculate number offset from bitCount if offsetArg starts with #
var offsetParsed = input.parseState.TryGetBitfieldOffset(currTokenIdx++, out var offset, out var multiplyOffset);
Debug.Assert(offsetParsed);
if (!BitmapManager.TryValidateBitfieldOffset(offset, (byte)bitCount, multiplyOffset, out offset, out _))
throw new GarnetException("ERR bit offset is not an integer or out of range");
long value = default;
if (cmd == RespCommand.SET || cmd == RespCommand.INCRBY)
{
value = input.parseState.GetLong(currTokenIdx++);
}
var overflowType = (byte)BitFieldOverflow.WRAP;
if (currTokenIdx < input.parseState.Count)
{
var overflowTypeParsed = input.parseState.TryGetBitFieldOverflow(currTokenIdx, out var overflowTypeValue);
Debug.Assert(overflowTypeParsed);
overflowType = (byte)overflowTypeValue;
}
// Number of bits in signed number
// At most 64 bits can fit into encoding info
var typeInfo = (byte)(sign | bitCount);View on GitHub (pinned to 951b0fc683)
Solutions
- Use a smaller absolute bit offset that keeps offset + bitCount - 1 within the maximum bitmap size.
- If using the # multiplier syntax, reduce the multiplier so offset * bitCount does not overflow or exceed the bitmap limit.
- Validate the offset client-side before issuing BITFIELD: ensure it is non-negative and that offset + bitWidth - 1 <= maxBitmapBits.
Example fix
// before BITFIELD mykey SET u8 #9223372036854775807 200 // after BITFIELD mykey SET u8 #1000000 200
Defensive patterns
Strategy: validation
Validate before calling
// Client-side validation before BITFIELD
long maxBits = 512L * 1024 * 1024 * 8; // adjust to your max bitmap size
if (useHashOffset)
{
if (offset < 0 || offset > long.MaxValue / bitWidth)
throw new ArgumentException("Offset out of range");
long endBit = offset * bitWidth + bitWidth - 1;
if (endBit > maxBits) throw new ArgumentException("Bit offset exceeds max bitmap size");
}
else
{
if (offset < 0 || offset + bitWidth - 1 > maxBits)
throw new ArgumentException("Bit offset out of range");
} Try / catch
// Catch as part of RESP error handling
try { client.BitField(key, ops); }
catch (GarnetException ex) when (ex.Message.Contains("bit offset"))
{ /* return Redis-compatible error to client */ } Prevention
- Validate BITFIELD offsets client-side before sending the command.
- Cap multiplier offsets (# syntax) to prevent overflow in offset * bitWidth.
- Sanitize user input that feeds into BITFIELD offset calculations.
When it happens
Trigger: BITFIELD key with: a #N offset where N * bitCount overflows int64 (e.g., '#9223372036854775807' with u8); a negative offset; or an absolute offset whose end bit exceeds MaxBitmapPayloadBits. Also BITFIELD SET/INCRBY where the computed end position is out of range.
Common situations: Client sending BITFIELD with computed offsets from untrusted input; scripts generating BITFIELD commands with large multiplier offsets; migrating data from another system with very large bitmap keys.
Related errors
- ERR value is not an integer or out of range.
- Setting bitfield failed: Size of bitmap smaller than offset
- RI.SET: invalid arguments.
- RI.GET: invalid arguments.
- RI.DEL: invalid arguments.
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/f6e780d713fd28e8.
Report an issue: GitHub.