{"record":{"id":"7a36515bc1432602","repo":"dotnet/machinelearning","slug":"offset-must-be-non-negative-parameter-offset","errorCode":null,"errorMessage":"Offset must be non-negative. (Parameter 'offset')","messagePattern":"Offset must be non-negative\\. \\(Parameter 'offset'\\)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.Data/Utilities/StreamUtils.cs","lineNumber":201,"sourceCode":"        /// <param name=\"offset\">The integer \"offset\" argument passed to the reading or writing method.</param>\n        /// <param name=\"count\">The integer \"count\" argument passed to the reading or writing method.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"buffer\"/> was null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        /// <paramref name=\"offset\"/> was outside the bounds of <paramref name=\"buffer\"/>, or\n        /// <paramref name=\"count\"/> was negative, or the range specified by the combination of\n        /// <paramref name=\"offset\"/> and <paramref name=\"count\"/> exceed the length of <paramref name=\"buffer\"/>.\n        /// </exception>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static void ValidateBufferArguments(byte[] buffer, int offset, int count)\n        {\n            if (buffer is null)\n            {\n                throw new ArgumentNullException(nameof(buffer));\n            }\n\n            if (offset < 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(offset), \"Offset must be non-negative.\");\n            }\n\n            if ((uint)count > buffer.Length - offset)\n            {\n                throw new ArgumentOutOfRangeException(nameof(count), \"Count must be non-negative and count must not exceed buffer.Length - offset.\");\n            }\n        }\n\n        // No argument checking is done here. It is up to the caller.\n        private static int ReadAtLeastCore(Stream stream, byte[] buffer, int offset, int minimumBytes, bool throwOnEndOfStream)\n        {\n            Debug.Assert(minimumBytes <= buffer.Length);\n            int count = minimumBytes;\n            int totalRead = 0;\n            while (totalRead < minimumBytes)\n            {\n                int read = stream.Read(buffer, offset, count);\n                offset += read;","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.Data/Utilities/StreamUtils.cs#L183-L219","documentation":"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.","triggerScenarios":"Calling ReadExactly (or another ValidateBufferArguments-backed helper) with a negative offset, typically from an unvalidated computed offset (e.g. position - size going below zero).","commonSituations":"Accumulating offsets in loops that underflow; passing a negative variable after subtracting a header size; mixing up offset and position parameters.","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"],"exampleFix":"// before\nint offset = position - headerSize; // can go negative\nStreamUtils.ReadExactly(stream, buffer, offset, count);\n// after\nint offset = Math.Max(0, position - headerSize);\nStreamUtils.ReadExactly(stream, buffer, offset, count);","handlingStrategy":"validation","validationCode":"if (offset < 0) throw new ArgumentException(\"Offset must be non-negative\", nameof(offset));\nStreamUtils.ReadExactly(stream, buffer, offset, count);","typeGuard":null,"tryCatchPattern":"try { StreamUtils.ReadExactly(stream, buffer, offset, count); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"offset\")\n{ /* fix offset computation */ }","preventionTips":["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"],"tags":["argument-validation","out-of-range","stream"],"backgroundTag":"argument-out-of-range","analyzedSha":"7b76e69cf964daeca3f1377af6bc5543284d56c6","analyzedAt":"2026-09-11T12:35:38.930Z","contentChangedAt":"2026-09-11T12:35:38.930Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}