dotnet/aspnetcore · error · Error
Incomplete message.
Error message
Incomplete message.
What it means
Thrown when the declared message size (decoded from the prefix) exceeds the remaining bytes in the input ArrayBuffer — i.e. the prefix says N more bytes follow, but only fewer are present. Standard SignalR partial-frame condition: the parser received the length header but not the full body.
Solutions
- Buffer incoming bytes until at least (prefixLength + declaredSize) bytes are available before calling parse.
- If using the official signalr client and you see this, report it as a transport bug — the client should reassemble for you.
- On a real disconnect, propagate the error and reconnect with a fresh HubConnection.
Example fix
// before
const msgs = BinaryMessageFormat.parse(buffer); // partial body present
// after — accumulate until the declared size is fully present
const prefix = readVarint(buffer);
if (buffer.byteLength < prefix.bytes + prefix.size) {
return { needMore: true };
}
const msgs = BinaryMessageFormat.parse(buffer); Defensive patterns
Strategy: validation
Validate before calling
// Pre-check that the declared body is fully present
function hasFullBody(buf: Uint8Array, offset: number, maxLen: number): boolean {
let size = 0, numBytes = 0, byteRead;
do {
byteRead = buf[offset + numBytes];
size |= (byteRead & 0x7f) << (7 * numBytes);
numBytes++;
} while (numBytes < maxLen && (byteRead & 0x80) !== 0);
return buf.byteLength >= offset + numBytes + size;
} Type guard
function isCompleteFrame(buf: Uint8Array, offset: number): boolean {
// returns true only when prefix + declared body fit in buf
// (use hasFullBody implementation)
return hasFullBody(buf, offset, 5);
} Try / catch
try { return BinaryMessageFormat.parse(buf); }
catch (e) {
if (/Incomplete message/.test((e as Error).message)) {
pendingBuffer = concat(pendingBuffer, buf); return []; // wait for more
}
throw e;
} Prevention
- Buffer until prefix bytes + declared size are available.
- Prefer the official transport which reassembles frames automatically.
- On disconnect, propagate the error and reconnect.
When it happens
Trigger: Feeding BinaryMessageFormat.parse a buffer that contains a complete prefix but a truncated body. Common in custom transports that do not wait for the full frame, or when the WebSocket emitted a partial message and the caller did not buffer across reads.
Common situations: Custom transport integration that calls parse per chunk instead of accumulating; the official client expects the transport layer (WebSocket.onmessage) to deliver complete frames so end-users usually see this only when intercepting the stream; server disconnected mid-write.
Related errors
- Cannot read message size.
- MessagePack message was length
- Messages over 2GB in size are not supported
- The length header was incomplete
- Error reading length header.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/19eebd352650aeff.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts:63
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 3600ca084e)