dotnet/machinelearning · error · ArgumentOutOfRangeException

Count must be non-negative and count must not exceed…

Error message

Count must be non-negative and count must not exceed buffer.Length - offset. (Parameter 'count')

What it means

ValidateBufferArguments requires count to be non-negative and not exceed buffer.Length - offset, i.e. the requested read region must fit within the buffer. Violating either condition throws ArgumentOutOfRangeException for 'count'.

Solutions

  1. Ensure buffer.Length >= offset + count before the call, or allocate the buffer with enough room
  2. Validate/normalize count against the remaining buffer space
  3. Increase buffer allocation size to account for the offset

Example fix

// before
var buffer = new byte[100];
StreamUtils.ReadExactly(stream, buffer, 50, 100); // 50+100 > 100
// after
StreamUtils.ReadExactly(stream, buffer, 50, Math.Min(count, buffer.Length - 50));
Defensive patterns

Strategy: validation

Validate before calling

if (count < 0 || offset + count > buffer.Length)
    throw new ArgumentException("count must satisfy 0 <= count <= buffer.Length - offset");

Try / catch

try { StreamUtils.ReadExactly(stream, buffer, offset, count); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "count")
{ /* resize buffer or clamp count */ }

Prevention

When it happens

Trigger: Calling ReadExactly with count < 0, or with offset + count > buffer.Length, so the read would write past the end of the supplied buffer.

Common situations: Requesting more bytes than the buffer holds (hardcoded sizes vs actual allocation); forgetting that offset consumes buffer space; off-by-one errors when buffer length was sized for count-1.

Related errors


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

Appendix: source

Thrown at src/Microsoft.ML.Data/Utilities/StreamUtils.cs:206

        /// <paramref name="count"/> was negative, or the range specified by the combination of
        /// <paramref name="offset"/> and <paramref name="count"/> exceed the length of <paramref name="buffer"/>.
        /// </exception>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static void ValidateBufferArguments(byte[] buffer, int offset, int count)
        {
            if (buffer is null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), "Offset must be non-negative.");
            }

            if ((uint)count > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "Count must be non-negative and count must not exceed buffer.Length - offset.");
            }
        }

        // No argument checking is done here. It is up to the caller.
        private static int ReadAtLeastCore(Stream stream, byte[] buffer, int offset, int minimumBytes, bool throwOnEndOfStream)
        {
            Debug.Assert(minimumBytes <= buffer.Length);
            int count = minimumBytes;
            int totalRead = 0;
            while (totalRead < minimumBytes)
            {
                int read = stream.Read(buffer, offset, count);
                offset += read;
                count -= read;
                if (read == 0)
                {
                    if (throwOnEndOfStream)
                    {

View on GitHub (pinned to 7b76e69cf9)