dotnet/machinelearning · error · ArgumentNullException

Value cannot be null. (Parameter 'buffer')

Error message

Value cannot be null. (Parameter 'buffer')

What it means

StreamUtils.ValidateBufferArguments guards the byte[] arguments for ReadExactly and related helpers. A null buffer throws ArgumentNullException, mirroring the System.IO.Stream contract, because reading into a null buffer is meaningless.

Solutions

  1. Ensure the buffer is allocated (new byte[size]) before calling ReadExactly
  2. Add a null check or lazy initialization of the buffer at the call site
  3. Use a factory method that never returns null for buffer creation

Example fix

// before
byte[] buffer = GetBuffer(); // may return null
StreamUtils.ReadExactly(stream, buffer, 0, len);
// after
byte[] buffer = GetBuffer() ?? new byte[len];
StreamUtils.ReadExactly(stream, buffer, 0, len);
Defensive patterns

Strategy: validation

Validate before calling

if (buffer == null) throw new ArgumentNullException(nameof(buffer), "Allocate buffer before ReadExactly");
StreamUtils.ReadExactly(stream, buffer, offset, count);

Type guard

static bool IsValidBuffer(byte[] buffer) => buffer != null;

Try / catch

try { StreamUtils.ReadExactly(stream, buffer, offset, count); }
catch (ArgumentNullException ex) when (ex.ParamName == "buffer")
{ /* re-initialize buffer */ }

Prevention

When it happens

Trigger: Calling StreamUtils.ReadExactly(stream, null, offset, count) or another helper that routes through ValidateBufferArguments with a null byte[] buffer.

Common situations: A buffer field/property that was never initialized; a method returning null on allocation failure that is passed straight through; refactorings that changed buffer ownership.

Related errors


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

Appendix: source

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

        }
#endif

        /// <summary>Validates arguments provided to reading and writing methods on <see cref="Stream"/>.</summary>
        /// <param name="buffer">The array "buffer" argument passed to the reading or writing method.</param>
        /// <param name="offset">The integer "offset" argument passed to the reading or writing method.</param>
        /// <param name="count">The integer "count" argument passed to the reading or writing method.</param>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> was null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="offset"/> was outside the bounds of <paramref name="buffer"/>, or
        /// <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;

View on GitHub (pinned to 7b76e69cf9)