microsoft/garnet · error · InvalidOperationException
Read is not supported for DiskStreamWriteBuffer
Error message
Read is not supported for DiskStreamWriteBuffer
What it means
DiskStreamWriteBuffer is write-only; its Read implementation throws InvalidOperationException. It exists to serialize objects into the object log and holds a pinned memory stream for writing only. Reading from it is a misuse — the caller invoked a read-side operation on a write-side buffer.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/Allocator/ObjectSerialization/ObjectLogWriter.cs:333
// If we haven't yet instantiated the serializer do so now.
if (valueObjectSerializer is null)
{
pinnedMemoryStream = new(this);
valueObjectSerializer = storeFunctions.CreateValueObjectSerializer();
valueObjectSerializer.BeginSerialize(pinnedMemoryStream);
}
valueObjectSerializer.Serialize(valueObject);
OnSerializeComplete(valueObject);
}
void OnSerializeComplete(IHeapObject valueObject)
{
inSerialize = false;
}
/// <inheritdoc/>
public int Read(Span<byte> destinationSpan, CancellationToken cancellationToken = default) => throw new InvalidOperationException("Read is not supported for DiskStreamWriteBuffer");
/// <inheritdoc/>
public void Dispose()
{
var localMemoryStream = Interlocked.Exchange(ref pinnedMemoryStream, null);
if (localMemoryStream is not null)
{
// End serialization before disposing the pinned memory stream as it may try to flush final data which would use the pinnedMemoryStream.
valueObjectSerializer?.EndSerialize();
localMemoryStream.Dispose();
}
}
}
}View on GitHub (pinned to 951b0fc683)
Solutions
- Check the buffer type or a CanRead flag before calling Read.
- Use distinct pools/types for read vs write buffers so a reader never gets a DiskStreamWriteBuffer.
- Ensure the deserialization path receives a DiskStreamReadBuffer, not a write buffer.
Example fix
// before
int n = buffer.Read(dest, cancellationToken);
// after
if (buffer is DiskStreamWriteBuffer)
throw new InvalidOperationException("Cannot read from a write buffer");
int n = buffer.Read(dest, cancellationToken); Defensive patterns
Strategy: type-guard
Validate before calling
if (buffer is DiskStreamWriteBuffer) throw new InvalidOperationException("Cannot Read from a write buffer");
int n = buffer.Read(dest, cancellationToken); Type guard
static bool CanRead(IStreamBuffer b) => b is not DiskStreamWriteBuffer;
Prevention
- Keep read and write buffer pools separate.
- Check buffer direction before invoking read operations.
When it happens
Trigger: Calling Read(Span<byte>) on an IStreamBuffer that is actually a DiskStreamWriteBuffer — e.g. deserialization code that received a write buffer from a shared pool or a misrouted buffer reference.
Common situations: Generic buffer-pool code calling Read on any returned buffer; a refactor routing a write buffer into a read/deserialize path; shared IStreamBuffer handling not distinguishing buffer direction.
Related errors
- FlushAndReset is not supported for DiskStreamReadBuffer
- Write is not supported for DiskStreamReadBuffer
- {nameof(settings.LogSettings.NumberOfFlushBuffers)} must be
- {nameof(settings.LogSettings.NumberOfDeserializationBuffers)
- {nameof(settings.LogSettings.ObjectLogSegmentSizeBits)} must
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/6938d08c337afa9e.
Report an issue: GitHub.