dotnet/aspnetcore · error · RuntimeException
The length header was incomplete
Error message
The length header was incomplete
What it means
readLengthHeader reads the varint prefix byte-by-byte; if the buffer runs out of bytes before a terminating varint byte (MSB clear) is reached, the header is incomplete and the message cannot be framed.
Source
Thrown at src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/Utils.java:37
// VarInt: 0x35 - %00110101 - the most significant bit is 0 so the value is %x0110101 i.e. 0x35 (53)
// VarInt: 0x80 0x25 - %10000000 %00101001 - the most significant bit of the first byte is 1 so the
// remaining bits (%x0000000) are the lowest bits of the value. The most significant bit of the second
// byte is 0 meaning this is last byte of the VarInt. The actual value bits (%x0101001) need to be
// prepended to the bits we already read so the values is %01010010000000 i.e. 0x1480 (5248)
// We support payloads up to 2GB so the biggest number we support is 7fffffff which when encoded as
// VarInt is 0xFF 0xFF 0xFF 0xFF 0x07 - hence the maximum length prefix is 5 bytes.
int length = 0;
int numBytes = 0;
int maxLength = 5;
byte curr;
do {
// If we run out of bytes before we finish reading the length header, the message is malformed
if (buffer.hasRemaining()) {
curr = buffer.get();
} else {
throw new RuntimeException("The length header was incomplete");
}
length = length | (curr & (byte) 0x7f) << (numBytes * 7);
numBytes++;
} while (numBytes < maxLength && (curr & (byte) 0x80) != 0);
// Max header length is 5, and the maximum value of the 5th byte is 0x07
if ((curr & (byte) 0x80) != 0 || (numBytes == maxLength && curr > (byte) 0x07)) {
throw new RuntimeException("Messages over 2GB in size are not supported");
}
return length;
}
public static ArrayList<Byte> getLengthHeader(int length) {
// This code writes length prefix of the message as a VarInt. Read the comment in
// the readLengthHeader for details.
ArrayList<Byte> header = new ArrayList<Byte>();View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure the transport reassembles complete frames before handing them to the protocol.
- Verify the peer is not sending partial frames.
- Check for framing/offset bugs if you layer a custom transport.
Defensive patterns
Strategy: try-catch
Try / catch
// Java
try {
hubConnection.start().blockingAwait();
} catch (RuntimeException ex) {
if (ex.getMessage() != null && ex.getMessage().contains("length header was incomplete")) {
}
} Prevention
- Make the transport reassemble complete frames before delivery.
- Verify the peer is not sending partial frames.
- Handle connection close to avoid parsing fragments.
When it happens
Trigger: Buffer ends mid-varint; a payload containing only a partial length prefix; transport delivers a fragment rather than a complete frame.
Common situations: Truncated transport read; incorrect frame reassembly; connection drop mid-frame; proxy splitting the stream.
Related errors
- Cannot read message size.
- Messages bigger than 2GB are not supported.
- Incomplete message.
- MessagePack message was length %d but claimed to be length %
- Error reading length header.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/6715761ea4f81605.
Report an issue: GitHub.