clockworklabs/SpacetimeDB · error · InvalidOperationException
Unknown compression type
Error message
Unknown compression type
What it means
Every ServerMessage arriving over the websocket starts with one byte naming the compression algorithm (0=None, 1=Brotli, 2=Gzip). CompressionHelpers.DecompressDecodeMessage casts that byte to the CompressionAlgos enum and throws InvalidOperationException for any other value. The client's parse loop catches it, logs the exception, fails pending operations and disconnects — so the observable effect is a dropped connection.
Source
Thrown at sdks/csharp/src/CompressionHelpers.cs:64
/// Ensures efficient decompression by reading the entire stream at once to avoid
/// performance issues with certain stream implementations.
/// Throws <see cref="InvalidOperationException"/> if an unknown compression type is encountered.
/// </summary>
/// <param name="bytes">The compressed and encoded server message as a byte array.</param>
/// <returns>The deserialized <see cref="ServerMessage"/> object.</returns>
internal static ServerMessage DecompressDecodeMessage(byte[] bytes)
{
using var stream = new MemoryStream(bytes);
// The stream will never be empty. It will at least contain the compression algo.
var compression = (CompressionAlgos)stream.ReadByte();
// Conditionally decompress and decode.
Stream decompressedStream = compression switch
{
CompressionAlgos.None => stream,
CompressionAlgos.Brotli => BrotliReader(stream),
CompressionAlgos.Gzip => GzipReader(stream),
_ => throw new InvalidOperationException("Unknown compression type"),
};
// TODO: consider pooling these.
// DO NOT TRY TO TAKE THIS OUT. The BrotliStream ReadByte() implementation allocates an array
// PER BYTE READ. You have to do it all at once to avoid that problem.
MemoryStream memoryStream = new MemoryStream();
decompressedStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
return new ServerMessage.BSATN().Read(new BinaryReader(memoryStream));
}
/// <summary>
/// Prepare to read a BsatnRowList.
///
/// This could return an IEnumerable, but we return the reader and row count directly to avoid an allocation.
/// It is legitimate to repeatedly call <c>IStructuralReadWrite.Read<T></c> <c>rowCount</c> times on the resulting
/// BinaryReader:
/// Our decoding infrastructure guarantees that reading a value consumes the correct number of bytesView on GitHub (pinned to 524b4487d9)
Solutions
- Upgrade the C# SDK package to the release matching your server version
- As a workaround, reconnect with WithCompression(Compression.None) so a conformant server sends uncompressed messages (algo byte 0)
- If you feed raw bytes in tests, ensure the first byte is 0, 1 or 2 before injecting the message
- If SDK and server versions already match, capture the frame and report it as a SpacetimeDB bug
Example fix
// before
conn.OnMessageReceived(arbitraryBytes, DateTime.UtcNow); // fixture without algo byte
// after
var fixedBytes = new byte[] { (byte)CompressionAlgos.None }.Concat(arbitraryBytes).ToArray();
conn.OnMessageReceived(fixedBytes, DateTime.UtcNow); Defensive patterns
Strategy: validation
Validate before calling
// When injecting raw frames (tests), verify the algo byte first:
bool FrameHasKnownCompression(byte[] frame) =>
frame.Length > 0 && frame[0] is 0 or 1 or 2; // None, Brotli, Gzip Prevention
- Pin the C# SDK and SpacetimeDB server to the same release line
- Register OnDisconnect to surface decompression failures instead of silent drops
- Keep websocket frame fixtures prefixed with the compression byte
When it happens
Trigger: A server newer than the SDK using an algorithm this SDK version does not know (e.g. a newly introduced algo id >= 3); a corrupted/truncated websocket frame; or test code injecting arbitrary bytes through OnMessageReceived/IsTesting paths.
Common situations: Client SDK package older than a freshly upgraded SpacetimeDB server (version skew); pinned old SDK against maincloud; byte-level test fixtures that forgot the leading algo byte.
Related errors
- Brotli compression is not supported by the runtime. Please c
- Unexpected Compression Algorithm. Please use `gzip` or `none
- v3 websocket payloads must contain at least one message
- Failed to verify token: ${response.statusText}
- never types are not yet supported in C# output
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/df2ec2e262befd07.
Report an issue: GitHub.