{"record":{"id":"2f1a138184ce02c4","repo":"dotnet/aspnetcore","slug":"messages-bigger-than-2gb-are-not-supported","errorCode":null,"errorMessage":"Messages bigger than 2GB are not supported.","messagePattern":"Messages bigger than 2GB are not supported\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts","lineNumber":54,"sourceCode":"        const numBitsToShift = [0, 7, 14, 21, 28 ];\n\n        for (let offset = 0; offset < input.byteLength;) {\n            let numBytes = 0;\n            let size = 0;\n            let byteRead;\n            do {\n                byteRead = uint8Array[offset + numBytes];\n                size = size | ((byteRead & 0x7f) << (numBitsToShift[numBytes]));\n                numBytes++;\n            }\n            while (numBytes < Math.min(maxLengthPrefixSize, input.byteLength - offset) && (byteRead & 0x80) !== 0);\n\n            if ((byteRead & 0x80) !== 0 && numBytes < maxLengthPrefixSize) {\n                throw new Error(\"Cannot read message size.\");\n            }\n\n            if (numBytes === maxLengthPrefixSize && byteRead > 7) {\n                throw new Error(\"Messages bigger than 2GB are not supported.\");\n            }\n\n            if (uint8Array.byteLength >= (offset + numBytes + size)) {\n                // IE does not support .slice() so use subarray\n                result.push(uint8Array.slice\n                    ? uint8Array.slice(offset + numBytes, offset + numBytes + size)\n                    : uint8Array.subarray(offset + numBytes, offset + numBytes + size));\n            } else {\n                throw new Error(\"Incomplete message.\");\n            }\n\n            offset = offset + numBytes + size;\n        }\n\n        return result;\n    }\n}\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts#L36-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"Memory corruption in the transport; a malicious peer crafting oversized prefixes; a serialization bug producing absurd sizes; misinterpreting a non-MsgPack stream as MsgPack.","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."],"exampleFix":"// before\n// single SendAsync with a multi-GB payload\nawait connection.InvokeAsync(\"Process\", hugeBuffer);\n\n// after\n// stream in chunks\nawait foreach (var chunk in connection.StreamAsync<Chunk>(\"ProcessStream\", hugeBuffer)) { /* ... */ }","handlingStrategy":"validation","validationCode":"function validateMaxSize(prefixBytes) {\n  if (prefixBytes.length === 5 && prefixBytes[4] > 7) throw new Error('Frame too large; configure server max message size or stream the data.');\n}","typeGuard":"null","tryCatchPattern":"try { await connection.invoke('Process', payload); } catch (e) { if (/bigger than 2GB/i.test(e.message)) { /* switch to streaming */ } else throw e; }","preventionTips":["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."],"tags":["signalr","messagepack","framing","binary","size-limit","corruption"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}