dotnet/machinelearning · error · ArgumentOutOfRangeException
Offset must be non-negative. (Parameter 'offset')
Error message
Offset must be non-negative. (Parameter 'offset')
What it means
ValidateBufferArguments throws ArgumentOutOfRangeException for a negative offset. The (buffer, offset, count) triple must describe a valid region inside the buffer, and a negative offset cannot be, so the call is rejected before any I/O.
Solutions
- Clamp or validate offset >= 0 before the call
- Fix the computation that produces the offset (e.g. use Math.Max(0, value))
- Reorder logic so the offset is derived from bytes actually read
Example fix
// before int offset = position - headerSize; // can go negative StreamUtils.ReadExactly(stream, buffer, offset, count); // after int offset = Math.Max(0, position - headerSize); StreamUtils.ReadExactly(stream, buffer, offset, count);
Defensive patterns
Strategy: validation
Validate before calling
if (offset < 0) throw new ArgumentException("Offset must be non-negative", nameof(offset));
StreamUtils.ReadExactly(stream, buffer, offset, count); Try / catch
try { StreamUtils.ReadExactly(stream, buffer, offset, count); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "offset")
{ /* fix offset computation */ } Prevention
- Clamp computed offsets with Math.Max(0, x)
- Never subtract sizes from positions without bounding the result
- Validate (buffer, offset, count) triples in helper methods before delegating to stream reads
When it happens
Trigger: Calling ReadExactly (or another ValidateBufferArguments-backed helper) with a negative offset, typically from an unvalidated computed offset (e.g. position - size going below zero).
Common situations: Accumulating offsets in loops that underflow; passing a negative variable after subtracting a header size; mixing up offset and position parameters.
Related errors
- Count must be non-negative and count must not exceed…
- Value cannot be null. (Parameter 'buffer')
- ArgumentNullException(nameof(column))
- Bad comparer
- Dimension must be divisible by 2
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/7a36515bc1432602.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.ML.Data/Utilities/StreamUtils.cs:201
/// <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;
int totalRead = 0;
while (totalRead < minimumBytes)
{
int read = stream.Read(buffer, offset, count);
offset += read;View on GitHub (pinned to 7b76e69cf9)