dotnet/aspnetcore · error
Invalid input for MessagePack hub protocol. Expected an Arra
Error message
Invalid input for MessagePack hub protocol. Expected an ArrayBuffer.
What it means
Thrown by MessagePackHubProtocol.parseMessages() when the incoming data is not an ArrayBuffer. The IHubProtocol interface technically permits string input, but this binary-only implementation rejects anything that fails isArrayBuffer() (a plain string, a Uint8Array, or a DataView). It exists because MessagePack is a binary transfer format and the @msgpack/msgpack decoder requires raw bytes. The guard at line 75 makes the mismatch fail fast with a clear message instead of corrupting deeper inside the decoder.
Source
Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts:76
messagePackOptions.extensionCodec,
messagePackOptions.context,
messagePackOptions.maxStrLength,
messagePackOptions.maxBinLength,
messagePackOptions.maxArrayLength,
messagePackOptions.maxMapLength,
messagePackOptions.maxExtLength,
);
}
/** Creates an array of HubMessage objects from the specified serialized representation.
*
* @param {ArrayBuffer} input An ArrayBuffer containing the serialized representation.
* @param {ILogger} logger A logger that will be used to log messages that occur during parsing.
*/
public parseMessages(input: ArrayBuffer, logger: ILogger): HubMessage[] {
// The interface does allow "string" to be passed in, but this implementation does not. So let's throw a useful error.
if (!(isArrayBuffer(input))) {
throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer.");
}
if (logger === null) {
logger = NullLogger.instance;
}
const messages = BinaryMessageFormat.parse(input);
const hubMessages = [];
for (const message of messages) {
const parsedMessage = this._parseMessage(message, logger);
// Can be null for an unknown message. Unknown message is logged in parseMessage
if (parsedMessage) {
hubMessages.push(parsedMessage);
}
}
return hubMessages;View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure the connection is created with a transport that supports binary (WebSockets default, or LongPolling/Fetch which handle binary) and that the server agrees on the messagepack protocol.
- If you call parseMessages directly, convert the input first: parseMessages(myBuffer.buffer ? myBuffer.buffer : myBuffer, logger) for ArrayBuffer, or copy a Uint8Array via new Uint8Array(...).buffer.
- Verify you are not feeding a string: wrap with new TextEncoder().encode(str) only if you genuinely have msgpack bytes serialized as a string (rare); otherwise switch to the JSON protocol.
- Double-check that the data passed comes from a binary transferFormat connection (this.transferFormat === TransferFormat.Binary).
Example fix
// before const messages = protocol.parseMessages(receivedString, logger); // after // only call with the underlying ArrayBuffer from a binary transport const messages = protocol.parseMessages(receivedArrayBuffer, logger);
Defensive patterns
Strategy: validation
Validate before calling
// before calling parseMessages, ensure binary input
function toArrayBuffer(input: unknown): ArrayBuffer {
if (input instanceof ArrayBuffer) return input;
if (ArrayBuffer.isView(input as ArrayBufferView)) {
return (input as Uint8Array).buffer.slice(
(input as Uint8Array).byteOffset,
(input as Uint8Array).byteOffset + (input as Uint8Array).byteLength,
);
}
throw new TypeError('parseMessages requires an ArrayBuffer');
}
const messages = protocol.parseMessages(toArrayBuffer(data), logger); Type guard
import { isArrayBuffer } from '@microsoft/signalr-protocol-msgpack/dist/esm/Utils';
function isParsable(data: unknown): data is ArrayBuffer {
return isArrayBuffer(data);
} Try / catch
try {
const messages = protocol.parseMessages(data as ArrayBuffer, logger);
} catch (e) {
if (e.message.includes('Expected an ArrayBuffer')) {
// convert and retry, or report a transport misconfiguration
throw new Error('MessagePack protocol requires a binary transport');
}
throw e;
} Prevention
- Always create the HubConnection over a transport negotiated for TransferFormat.Binary.
- If you call parseMessages directly, normalize input through an ArrayBuffer coercion helper.
- Unit-test the protocol path with both ArrayBuffer and Uint8Array to catch shape mismatches early.
When it happens
Trigger: Calling messagePackProtocol.parseMessages(someString, logger) where someString is a JS string; passing a Uint8Array or Node Buffer (both fail isArrayBuffer); wiring the protocol over a Text (non-binary) WebSocket transport that delivers string chunks.
Common situations: Migrating from the JSON protocol and forgetting that the transport must negotiate TransferFormat.Binary; a custom transport or proxy that re-encodes frames as text; a server that downgrades the connection to text format; older browsers/Node where fetch/XHR surface data as a non-ArrayBuffer type.
Related errors
- Invalid message type.
- Invalid payload.
- 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/842fff606255ff97.
Report an issue: GitHub.