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

  1. Verify the source file/stream is complete and untruncated (re-download or regenerate it)
  2. Use TryReadVarInt instead of ReadVarInt when the end of stream is an expected condition
  3. Check that the reader's position starts at a valid chunk boundary (0 or after a fully read chunk)
  4. 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

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


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)