dotnet/aspnetcore · error
Invalid payload.
Error message
Invalid payload.
What it means
Thrown in _parseMessage when an individual frame extracted by BinaryMessageFormat.parse has length 0. BinaryMessageFormat already split the buffer on varint length prefixes, so a zero-length frame means the wire data was structurally broken (a length prefix pointed at an empty payload). This is a defense against feeding garbage to the msgpack decoder.
Source
Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts:129
return this._writeCompletion(message as CompletionMessage);
case MessageType.Ping:
return BinaryMessageFormat.write(SERIALIZED_PING_MESSAGE);
case MessageType.CancelInvocation:
return this._writeCancelInvocation(message as CancelInvocationMessage);
case MessageType.Close:
return this._writeClose();
case MessageType.Ack:
return this._writeAck(message as AckMessage);
case MessageType.Sequence:
return this._writeSequence(message as SequenceMessage);
default:
throw new Error("Invalid message type.");
}
}
private _parseMessage(input: Uint8Array, logger: ILogger): HubMessage | null {
if (input.length === 0) {
throw new Error("Invalid payload.");
}
const properties = this._decoder.decode(input) as any;
if (properties.length === 0 || !(properties instanceof Array)) {
throw new Error("Invalid payload.");
}
const messageType = properties[0] as MessageType;
switch (messageType) {
case MessageType.Invocation:
return this._createInvocationMessage(this._readHeaders(properties), properties);
case MessageType.StreamItem:
return this._createStreamItemMessage(this._readHeaders(properties), properties);
case MessageType.Completion:
return this._createCompletionMessage(this._readHeaders(properties), properties);
case MessageType.Ping:
return this._createPingMessage(properties);View on GitHub (pinned to 294cab2f9b)
Solutions
- Capture the raw bytes at the transport layer and verify the varint length prefixes are consistent with the available bytes before parsing.
- Check the SignalR server and client protocol versions match (both should support MessagePack v2).
- Inspect the connection for middleware/proxies that may alter the binary stream (e.g. a text-mode reverse proxy).
- Add a try/catch around the connection's onreceive handler to log the offending buffer length and reconnect.
Example fix
// before
const hubMessages = protocol.parseMessages(rawBuffer, logger);
// after
try {
const hubMessages = protocol.parseMessages(rawBuffer, logger);
} catch (e) {
logger.log(LogLevel.Error, 'Corrupt msgpack frame, reconnecting: ' + e.message);
await connection.stop();
await connection.start();
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate varint length prefixes before parsing
function framesLookComplete(buffer: ArrayBuffer): boolean {
const u = new Uint8Array(buffer);
for (let i = 0; i < u.length;) {
let len = 0, shift = 0, n = 0, b;
do { b = u[i + n]; len |= (b & 0x7f) << shift; shift += 7; n++; }
while (n < 5 && (b & 0x80) !== 0);
if (len === 0) return false; // a zero-length frame will trigger error 102
i += n + len;
if (i > u.length) return false;
}
return true;
} Try / catch
try {
const msgs = protocol.parseMessages(buffer, logger);
} catch (e) {
if (e.message === 'Invalid payload.') {
logger.log(LogLevel.Error, 'Zero-length msgpack frame; reconnecting.');
await connection.start();
return;
}
throw e;
} Prevention
- Treat any zero-length frame as unrecoverable corruption and reconnect.
- Do not share the ArrayBuffer being parsed with code that writes to it concurrently.
- Log the raw buffer length at the transport boundary to spot truncation.
When it happens
Trigger: Corrupt or truncated binary frame where a varint length prefix is followed by zero bytes; a man-in-the-middle or proxy that strips payload bytes; manually constructing a buffer with a 0x00 length prefix then data.
Common situations: Network interruption mid-frame leaving a partial buffer that the length prefix claims is empty; a bug in a custom transport that pre-slices frames incorrectly; version skew where an old server emits a frame shape the client cannot interpret.
Related errors
- Message is incomplete.
- Invalid payload for Close message.
- Invalid payload for Ping message.
- Cannot read message size.
- Messages bigger than 2GB are not supported.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/e7a004bd939ef754.
Report an issue: GitHub.