dotnet/aspnetcore · error
Messages bigger than 2GB are not supported.
Error message
Messages bigger than 2GB are not supported.
What it means
Thrown by BinaryMessageFormat.parse when the length prefix is a full 5 bytes long (the maximum) and the 5th byte is greater than 7. The VarInt decoding uses 7 bits per byte; 5 bytes give 35 bits, but JS bitwise ops are 32-bit and the design caps at 2^32, so a 5th byte > 7 would imply a payload larger than ~2GB, which the runtime explicitly refuses.
Source
Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts:54
const numBitsToShift = [0, 7, 14, 21, 28 ];
for (let offset = 0; offset < input.byteLength;) {
let numBytes = 0;
let size = 0;
let byteRead;
do {
byteRead = uint8Array[offset + numBytes];
size = size | ((byteRead & 0x7f) << (numBitsToShift[numBytes]));
numBytes++;
}
while (numBytes < Math.min(maxLengthPrefixSize, input.byteLength - offset) && (byteRead & 0x80) !== 0);
if ((byteRead & 0x80) !== 0 && numBytes < maxLengthPrefixSize) {
throw new Error("Cannot read message size.");
}
if (numBytes === maxLengthPrefixSize && byteRead > 7) {
throw new Error("Messages bigger than 2GB are not supported.");
}
if (uint8Array.byteLength >= (offset + numBytes + size)) {
// IE does not support .slice() so use subarray
result.push(uint8Array.slice
? uint8Array.slice(offset + numBytes, offset + numBytes + size)
: uint8Array.subarray(offset + numBytes, offset + numBytes + size));
} else {
throw new Error("Incomplete message.");
}
offset = offset + numBytes + size;
}
return result;
}
}
View on GitHub (pinned to 294cab2f9b)
Solutions
- Cap and validate message sizes server-side (configure maximum receive message size on the SignalR hub).
- Stream large payloads instead of single frames (IAsyncEnumerable / streaming).
- If untrusted, treat this as a protocol violation and terminate the connection.
- Verify you are not pointing a MsgPack parser at a JSON or text stream.
Example fix
// before
// single SendAsync with a multi-GB payload
await connection.InvokeAsync("Process", hugeBuffer);
// after
// stream in chunks
await foreach (var chunk in connection.StreamAsync<Chunk>("ProcessStream", hugeBuffer)) { /* ... */ } Defensive patterns
Strategy: validation
Validate before calling
function validateMaxSize(prefixBytes) {
if (prefixBytes.length === 5 && prefixBytes[4] > 7) throw new Error('Frame too large; configure server max message size or stream the data.');
} Type guard
null
Try / catch
try { await connection.invoke('Process', payload); } catch (e) { if (/bigger than 2GB/i.test(e.message)) { /* switch to streaming */ } else throw e; } Prevention
- Configure a sensible maximum receive message size on the hub.
- Stream large data via IAsyncEnumerable/channels instead of single frames.
- Do not feed non-MsgPack bytes to the MsgPack protocol.
When it happens
Trigger: A legitimately enormous MessagePack frame (>2GB), or (far more commonly) a corrupt/attacker-controlled prefix whose high bytes are set. SignalR MsgPack frames in practice should be far smaller; hitting this usually means the prefix bytes are garbage rather than a real payload size.
Common situations: Memory corruption in the transport; a malicious peer crafting oversized prefixes; a serialization bug producing absurd sizes; misinterpreting a non-MsgPack stream as MsgPack.
Related errors
- Cannot read message size.
- Incomplete message.
- MessagePack message was length %d but claimed to be length %
- The length header was incomplete
- Messages over 2GB in size are not supported
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/2f1a138184ce02c4.
Report an issue: GitHub.