stride3d/stride · error · IOException
Unexpected end of stream
Error message
Unexpected end of stream
What it means
LZ4Stream.TryReadVarInt reads a LEB128-style varint byte-by-byte from the inner stream. If the stream ends before a complete varint is read (and no partial result has accumulated), it throws IOException('Unexpected end of stream').
Solutions
- Verify the source file/stream is complete and untruncated (re-download or regenerate it)
- Use TryReadVarInt instead of ReadVarInt when the end of stream is an expected condition
- Check that the reader's position starts at a valid chunk boundary (0 or after a fully read chunk)
- Confirm writer and reader use the same LZ4Stream format/version
Example fix
// before
ulong len = stream.ReadVarInt(); // throws on truncation
// after
if (!stream.TryReadVarInt(out var len))
return false; // graceful end-of-stream Defensive patterns
Strategy: try-catch
Validate before calling
if (stream.Position >= stream.Length) return false; // nothing left to read
Try / catch
try { ok = lz4Stream.TryReadVarInt(out var v); }
catch (IOException) { ok = false; /* truncated stream */ } Prevention
- Prefer TryReadVarInt when EOF is a valid outcome
- Validate compressed files are complete before processing
- Keep producer and consumer LZ4Stream versions aligned
When it happens
Trigger: Reading a truncated LZ4-compressed stream; calling ReadVarInt at a position past the compressed data; the stream was closed or the file was cut short mid-chunk-header.
Common situations: Incomplete downloads of compressed asset files; reading an LZ4 stream produced by a newer/older format version; a writer crashed mid-flush leaving partial data.
Related errors
- Can't read beyond end of stream.
- Chunks with multiple passes are not supported.
- Count cannot be less than zero
- Operation 'SetPosition' is not supported
- Operation 'Read' is not supported
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/a994836a3ef463c3.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Serialization/Serialization/LZ4/LZ4Stream.cs:169
=> new($"Operation '{operationName}' is not supported");
/// <summary>Tries to read variable length int.</summary>
/// <param name="result">The result.</param>
/// <returns><c>true</c> if integer has been read, <c>false</c> if end of stream has been
/// encountered at the start of a value.</returns>
/// <exception cref="IOException">If end of stream has been encoutered in the middle of a value.</exception>
private bool TryReadVarInt(out ulong result)
{
var buffer = new byte[1];
var count = 0;
result = 0;
while (true)
{
if ((compressedSize != -1 && innerStreamPosition >= compressedSize) || innerStream.Read(buffer, 0, 1) == 0)
{
if (count == 0) return false;
throw new IOException("Unexpected end of stream");
}
innerStreamPosition++;
var b = buffer[0];
result += (ulong)(b & 0x7F) << count;
count += 7;
if ((b & 0x80) == 0 || count >= 64) break;
}
return true;
}
/// <summary>Reads the variable length int. Work with assumption that value is in the stream
/// and throws exception if it isn't. If you want to check if value is in the stream
/// use <see cref="TryReadVarInt"/> instead.</summary>
/// <returns>The value.</returns>
/// <exception cref="IOException">The end of the stream was unexpectedly reached.</exception>
private ulong ReadVarInt()
{View on GitHub (pinned to 96fad776d2)