dotnet/machinelearning · error · ArgumentException

Strings.InconsistentNullBitMapAndLength

Error message

Strings.InconsistentNullBitMapAndLength

What it means

Microsoft.Data.Analysis throws this ArgumentException when constructing a PrimitiveColumnContainer from a raw Apache Arrow-style null bit map whose byte length is shorter than required for the declared number of rows. The validity bitmap must have at least `bitMapBufferLength` bytes (ceil(length/8) padded per buffer); a shorter buffer would cause out-of-bounds reads when reading validity bits. The parameter name `nullBitMap` is attached to the exception.

Source

Thrown at src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs:92

                    bitMap.IncreaseSize(bitMapBufferLength);

                    var span = bitMap.Span;
                    span.Fill(255);
                    int lastByte = 1 << (length - (bitMapBufferLength - 1) * 8);
                    span[bitMapBufferLength - 1] = (byte)(lastByte - 1);

                    nullDataFrameBuffer = bitMap;
                }
                else
                {
                    nullDataFrameBuffer = new DataFrameBuffer<byte>();
                }
            }
            else
            {
                if (nullBitMap.Length < bitMapBufferLength)
                {
                    throw new ArgumentException(Strings.InconsistentNullBitMapAndLength, nameof(nullBitMap));
                }
                nullDataFrameBuffer = new ReadOnlyDataFrameBuffer<byte>(nullBitMap, bitMapBufferLength);
            }
            NullBitMapBuffers.Add(nullDataFrameBuffer);
            Length = length;
            NullCount = nullCount;
        }

        public PrimitiveColumnContainer(long length = 0, T? defaulValue = null)
        {
            AppendMany(defaulValue, length);
        }

        public void Resize(long length)
        {
            if (length < Length)
                throw new ArgumentException(Strings.CannotResizeDown, nameof(length));
            AppendMany(default, length - Length);

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Compute bitMapBufferLength the same way the library does (padded per MaxCapacity buffer) and ensure nullBitMap.Length >= bitMapBufferLength before constructing.
  2. If the bitmap covers fewer rows, either grow it (allocate a new byte array of the correct size and copy) or reduce the `length` argument to match the bitmap.
  3. Check the producer of the bitmap: truncation during I/O or a version skew in the Arrow serialization is a common cause; re-serialize the source data.

Example fix

// before
container = new PrimitiveColumnContainer<T>(values, nullBitMap, length: 1000); // bitmap only for 500 rows
// after
int bitMapBufferLength = (int)(((length + 63) / 64) * 8); // match library padding
if (nullBitMap.Length < bitMapBufferLength)
{
    var grown = new byte[bitMapBufferLength];
    Array.Copy(nullBitMap, grown, nullBitMap.Length);
    nullBitMap = grown;
}
container = new PrimitiveColumnContainer<T>(values, nullBitMap, length: 1000);
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidNullBitMap(byte[] nullBitMap, long length, long bitMapBufferLength) => nullBitMap != null && nullBitMap.Length >= bitMapBufferLength && length >= 0;

Type guard

if (nullBitMap == null || nullBitMap.Length < bitMapBufferLength) return; // reject before constructing container

Try / catch

try { var c = new PrimitiveColumnContainer<T>(values, nullBitMap, length); }
catch (ArgumentException ex) when (ex.ParamName == "nullBitMap")
{
    // grow or recompute the bitmap, then retry
}

Prevention

When it happens

Trigger: Calling the PrimitiveColumnContainer constructor that accepts a prebuilt nullBitMap byte array plus a length, where nullBitMap.Length < bitMapBufferLength (e.g. passing a bitmap computed for fewer rows than the `length` argument, or a bitmap missing Arrow's 8-byte-per-buffer alignment padding).

Common situations: Interoperating with Arrow IPC data where the caller miscomputes the bitmap buffer length (forgetting per-record-buffer padding to 64 bytes), deserializing a truncated/older file format, or hand-crafting a bitmap for a subset of rows while claiming the full column length.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/c6c93a377efac71f. Report an issue: GitHub.