{"record":{"id":"1137287d647cecf6","repo":"dotnet/machinelearning","slug":"unable-to-read-beyond-the-end-of-the-stream","errorCode":null,"errorMessage":"Unable to read beyond the end of the stream.","messagePattern":"Unable to read beyond the end of the stream\\.","errorType":"exception","errorClass":"EndOfStreamException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.Data/Utilities/StreamUtils.cs","lineNumber":225,"sourceCode":"            }\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;\n                count -= read;\n                if (read == 0)\n                {\n                    if (throwOnEndOfStream)\n                    {\n                        throw new EndOfStreamException(\"Unable to read beyond the end of the stream.\");\n                    }\n\n                    return totalRead;\n                }\n\n                totalRead += read;\n            }\n\n            return totalRead;\n        }\n\n        /// <summary>\n        /// Reads <paramref name=\"count\"/> number of bytes from the current stream and advances the position within the stream.\n        /// </summary>\n        /// <param name=\"stream\"></param>\n        /// <param name=\"buffer\">\n        /// An array of bytes. When this method returns, the buffer contains the specified byte array with the values\n        /// between <paramref name=\"offset\"/> and (<paramref name=\"offset\"/> + <paramref name=\"count\"/> - 1) replaced","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.Data/Utilities/StreamUtils.cs#L207-L243","documentation":"ReadAtLeastCore reads repeatedly until the requested minimum bytes are read; if the stream returns 0 bytes (end of stream) and throwOnEndOfStream is true, it throws EndOfStreamException('Unable to read beyond the end of the stream.'), matching Stream.ReadExactly semantics.","triggerScenarios":"Calling ReadExactly for N bytes when the underlying stream contains fewer than N bytes remaining (truncated file, closed network stream, already fully consumed stream).","commonSituations":"Parsing binary formats whose length header disagrees with actual payload size; truncated/corrupt downloads; reading past the end when the stream position was left at EOF by earlier code; network streams closed mid-transfer.","solutions":["Verify the stream length/remaining bytes >= requested count before calling ReadExactly, or use the ReadAtLeast variant with throwOnEndOfStream:false","Reset the stream position (stream.Position = 0) if the data was already read","Check data integrity: the source may be truncated or the format header lies about sizes"],"exampleFix":"// before\nStreamUtils.ReadExactly(stream, buffer, 0, expectedSize); // throws on short stream\n// after\nif (stream.Length - stream.Position < expectedSize)\n    throw new InvalidDataException($\"Expected {expectedSize} bytes, only {stream.Length - stream.Position} available\");\nStreamUtils.ReadExactly(stream, buffer, 0, expectedSize);","handlingStrategy":"try-catch","validationCode":"bool canReadExactly = stream.CanSeek == false || (stream.Length - stream.Position) >= expectedBytes;","typeGuard":null,"tryCatchPattern":"try { StreamUtils.ReadExactly(stream, buffer, 0, expectedBytes); }\ncatch (EndOfStreamException ex) when (ex.Message.Contains(\"Unable to read beyond the end\"))\n{ // handle truncated input: abort, resync format parser, or re-download\n    throw new InvalidDataException(\"Stream ended before expected bytes were read\", ex); }","preventionTips":["Check stream.Length - stream.Position before exact reads on seekable streams","Validate file completeness (checksum/size) before parsing","Reset stream position if prior code may have consumed the stream","Treat EndOfStreamException during format parsing as corrupt/truncated input"],"tags":["stream","end-of-stream","truncated-data"],"backgroundTag":"file-read-failed","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"}