dotnet/aspnetcore · error · Error
Message is incomplete.
Error message
Message is incomplete.
What it means
Thrown by HandshakeProtocol.parseHandshakeResponse in the binary branch when the ArrayBuffer does not contain a RecordSeparator (0x1e) byte. The handshake response is JSON text terminated by a record separator, and for binary protocols it arrives as the first chunk of an ArrayBuffer. Absence of the separator means the handshake response hasn't fully arrived or is malformed.
Source
Thrown at src/SignalR/clients/ts/signalr/src/HandshakeProtocol.ts:35
}
/** @private */
export class HandshakeProtocol {
// Handshake request is always JSON
public writeHandshakeRequest(handshakeRequest: HandshakeRequestMessage): string {
return TextMessageFormat.write(JSON.stringify(handshakeRequest));
}
public parseHandshakeResponse(data: any): [any, HandshakeResponseMessage] {
let messageData: string;
let remainingData: any;
if (isArrayBuffer(data)) {
// Format is binary but still need to read JSON text from handshake response
const binaryData = new Uint8Array(data);
const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);
if (separatorIndex === -1) {
throw new Error("Message is incomplete.");
}
// content before separator is handshake response
// optional content after is additional messages
const responseLength = separatorIndex + 1;
messageData = String.fromCharCode.apply(null, Array.prototype.slice.call(binaryData.slice(0, responseLength)));
remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;
} else {
const textData: string = data;
const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);
if (separatorIndex === -1) {
throw new Error("Message is incomplete.");
}
// content before separator is handshake response
// optional content after is additional messages
const responseLength = separatorIndex + 1;
messageData = textData.substring(0, responseLength);View on GitHub (pinned to 294cab2f9b)
Solutions
- Buffer incoming bytes until a 0x1e separator is present before calling parseHandshakeResponse.
- Confirm the server URL points to a real SignalR hub endpoint.
- Check server logs — if it crashed or rejected the protocol it may never send a valid handshake response.
- Verify the negotiated protocol name is spelled correctly on the client.
Example fix
// before
const [remaining, resp] = handshakeProtocol.parseHandshakeResponse(incompleteBuffer);
// after
// accumulate until the record separator byte (0x1e) is present
if (new Uint8Array(buffer).indexOf(0x1e) === -1) {
// wait for more data
return;
}
const [remaining, resp] = handshakeProtocol.parseHandshakeResponse(buffer); Defensive patterns
Strategy: validation
Validate before calling
// buffer until the record separator (0x1e) is present (binary path)
const SEP = 0x1e;
function handshakeBufferComplete(buffer: ArrayBuffer): boolean {
return new Uint8Array(buffer).indexOf(SEP) !== -1;
}
if (!handshakeBufferComplete(buffer)) {
// wait for more data
return;
}
const [remaining, resp] = handshakeProtocol.parseHandshakeResponse(buffer); Try / catch
try {
const [remaining, resp] = handshakeProtocol.parseHandshakeResponse(buffer);
} catch (e) {
if (e.message === 'Message is incomplete.') {
// accumulate more bytes and retry once the separator arrives
return;
}
throw e;
} Prevention
- Buffer binary chunks until a 0x1e byte appears before parsing the handshake.
- Verify the endpoint is a real SignalR hub returning a proper binary handshake response.
- Log the first chunk's byte length and hex to spot truncation.
When it happens
Trigger: The binary handshake chunk delivered to parseHandshakeResponse is incomplete (separator not yet received); a chunk that is actually a later message, not the handshake; the server never sent a proper handshake response.
Common situations: A transport delivered a partial first frame (the separator is in the next chunk); network latency splitting the handshake; a non-SignalR endpoint answering the WebSocket; server-side error closing the connection before sending the handshake response.
Related errors
- Invalid payload.
- Invalid input for MessagePack hub protocol. Expected an Arra
- Invalid payload for Close message.
- Invalid payload for Ping message.
- Invalid payload for Invocation message.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/4594a02506260070.
Report an issue: GitHub.