JamesNK/Newtonsoft.Json · error · EndOfStreamException
Unable to read beyond the end of the stream.
Error message
Unable to read beyond the end of the stream.
What it means
Thrown by BsonReader.ReadString when the underlying stream returns zero bytes before the declared string length has been fully read. It is an EndOfStreamException meaning the BSON document declared more data than the stream actually contains. This almost always indicates a truncated or corrupt BSON payload.
Source
Thrown at Src/Newtonsoft.Json/Bson/BsonReader.cs:690
EnsureBuffers();
StringBuilder builder = null;
int totalBytesRead = 0;
// used in case of left over multibyte characters in the buffer
int offset = 0;
do
{
int count = ((length - totalBytesRead) > MaxCharBytesSize - offset)
? MaxCharBytesSize - offset
: length - totalBytesRead;
int byteCount = _reader.Read(_byteBuffer, offset, count);
if (byteCount == 0)
{
throw new EndOfStreamException("Unable to read beyond the end of the stream.");
}
totalBytesRead += byteCount;
// Above, byteCount is how many bytes we read this time.
// Below, byteCount is how many bytes are in the _byteBuffer.
byteCount += offset;
if (byteCount == length)
{
// pref optimization to avoid reading into a string builder
// first iteration and all bytes read then return string directly
int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
return new string(_charBuffer, 0, charCount);
}
else
{
int lastFullCharStop = GetLastFullCharStop(byteCount - 1);View on GitHub (pinned to 4f73e74372)
Solutions
- Verify the byte length of the stream matches the BSON document's internal length prefix before deserialization.
- Re-fetch or re-transmit the payload if it was truncated over the network; ensure the transport delivers the complete buffer.
- Wrap the read in a try/catch for EndOfStreamException and treat it as corrupt-data for the caller.
- Validate the first 4 bytes (document length) against the actual stream length as an integrity pre-check.
Example fix
// before: trusting a network stream directly
using var reader = new BsonReader(networkStream);
var obj = serializer.Deserialize(reader, typeof(Foo));
// after: buffer fully and validate length first
byte[] data = ReadFully(networkStream);
int docLen = BitConverter.ToInt32(data, 0);
if (data.Length < docLen) throw new InvalidDataException("truncated BSON");
using var reader = new BsonReader(new MemoryStream(data)); Defensive patterns
Strategy: validation
Validate before calling
byte[] data = ReadFully(stream);
int docLen = BitConverter.ToInt32(data, 0);
if (docLen <= 0 || data.Length < docLen)
throw new InvalidDataException($"BSON declares {docLen} bytes but stream has {data.Length}"); Type guard
static bool StreamContainsFullDocument(byte[] data)
{
if (data.Length < 4) return false;
int len = BitConverter.ToInt32(data, 0);
return len > 0 && data.Length >= len;
} Try / catch
try { var v = serializer.Deserialize(bsonReader, type); }
catch (System.IO.EndOfStreamException ex)
{
throw new InvalidDataException("BSON payload is truncated or corrupt", ex);
} Prevention
- Buffer the full payload before deserializing so truncation is detected up front.
- Validate the document length prefix against the actual byte count.
- Treat EndOfStreamException during BSON read as corrupt-data, not a transient error.
When it happens
Trigger: Reading a BSON document whose length-prefixed string (or C# string read path) declares N bytes, but the stream ends before N bytes are available. Also triggered when the document's top-level length prefix is wrong, causing the reader to over-read into nothing.
Common situations: Truncated network read that delivered only part of the BSON payload. A length prefix that was written with a wrong endianness or wrong value. Feeding a non-BSON stream that happens to start with plausible length bytes. Reading from a MemoryStream whose Capacity was misreported.
Related errors
- Unexpected BsonType value: {0}
- Expected Bytes but got {0}.
- Unexpected token when writing BSON: {0}
- An ObjectId must be 12 bytes
- No object created.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/c764ba90990407be.
Report an issue: GitHub.