microsoft/garnet · error · NotSupportedException
Stream does not support get_Length.
Error message
Stream does not support get_Length.
What it means
PinnedMemoryStream wraps an IStreamBuffer and serves data in chunks; because it does not hold the entire stream in one contiguous buffer, it cannot report a meaningful total Length. Its Length getter throws NotSupportedException by design. The stream is forward-only, chunked, and has no concept of a fixed total size.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/Allocator/ObjectSerialization/PinnedMemoryStream.cs:70
{
if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled(cancellationToken);
try
{
streamBuffer.FlushAndReset(cancellationToken);
return Task.CompletedTask;
}
catch (Exception ex)
{
return Task.FromException(ex);
}
}
/// <summary>The amount of data in the internal streamBuffer. Not supported because we chunk and thus may not have all data.</summary>
public override long Length
{
get => throw new NotSupportedException("Stream does not support get_Length.");
}
/// <summary>The current position of the stream seeking; not supported</summary>
public override long Position
{
get => throw new NotSupportedException("Stream does not support get_Position.");
set => throw new NotSupportedException("Stream does not support set_Position.");
}
/// <summary>Copy data from the internal streamBuffer into the buffer; the streamBuffer handles Flush, Reset, and Read more
/// (e.g. from disk or network) as needed.</summary>
/// <param name="buffer">Buffer to copy the bytes into.</param>
/// <param name="offset">Index in the buffer to start copying to.</param>
/// <param name="count">Desired number of bytes to copy to the buffer.</param>
/// <returns>Number of bytes actually read.</returns>
public override int Read(byte[] buffer, int offset, int count)
{
ValidateBufferArguments(buffer, offset, count);View on GitHub (pinned to 951b0fc683)
Solutions
- Do not query Length on PinnedMemoryStream; track byte counts yourself as you write/read.
- If a downstream API needs Length, buffer to a MemoryStream first, then forward (note: loses the streaming/pinning benefit).
- Serialize to the BinaryWriter passed to DoSerialize and avoid inspecting the underlying stream.
Example fix
// before
public void DoSerialize(BinaryWriter w)
{
var len = w.BaseStream.Length; // PinnedMemoryStream -> NotSupportedException
...
}
// after
public void DoSerialize(BinaryWriter w)
{
w.Write(_field); // no Length query needed
} Defensive patterns
Strategy: validation
Validate before calling
if (stream is PinnedMemoryStream pms) throw new NotSupportedException("Do not query Length on PinnedMemoryStream; track bytes manually");
var len = stream.Length; Type guard
static bool HasLength(Stream s) => s is not PinnedMemoryStream;
Prevention
- Never query Length/Position on object-log serialization streams.
- Track byte counts in your own counter while writing.
- Serialize only via the provided BinaryWriter.
When it happens
Trigger: Code that receives a PinnedMemoryStream (used by the object-log serializer as the BinaryWriter backing stream) and accesses its .Length property — e.g. a BinaryWriter, serializer, or third-party code querying Length.
Common situations: A custom IHeapObject serializer that checks stream.Length; wrapping PinnedMemoryStream in a component that requires Length (compression, hashing, length-prefixed framing); debug/logging code that reads Length.
Related errors
- Stream does not support get_Position.
- Stream does not support Seek.
- Advancing position by {size:N} bytes exceeds maximum object
- Object serialized size currently at {valueObjectBytesWritten
- Stream does not support SetLength.
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/db1970c96b99518e.
Report an issue: GitHub.