dotnet/aspnetcore · error · RuntimeException
Error reading MessagePack data.
Error message
Error reading MessagePack data.
What it means
The outer try in parseMessages catches MessagePackException (from the msgpack-core library) and IOException raised while unpacking the array header, message type, and message body. Any such failure - bad varint, unexpected token, truncated array - is wrapped as 'Error reading MessagePack data.' This is the general parse-failure sink for MessagePack message bodies.
Solutions
- Align server and client SignalR versions so the MessagePack message contracts match.
- Ensure all types used as hub method arguments are serializable by the MessagePack protocol on both sides (register custom formatters identically).
- Capture the failing payload (log the ByteBuffer before parse) and validate it with the MessagePack library standalone to localize the bad field.
- Temporarily switch the hub protocol to JSON to confirm the issue is MessagePack-specific, then fix the contract.
Example fix
// before - argument type not MessagePack-serializable on client
hub.invoke(MyCustomType.class, "Send", new MyCustomType());
// after - register symmetric formatters, or use JSON
// server: services.AddSignalR().AddMessagePackProtocol();
// client: ensure MyCustomType is MessagePack-compatible,
// or
HubConnectionBuilder.create(url)
.build(); // default JSON protocol on both ends Defensive patterns
Strategy: try-catch
Try / catch
hub.onClosed(ex -> {
if (ex != null && ex.getMessage().contains("Error reading MessagePack data")) {
// body parse failure; capture the failing payload, align contracts
log.error("MessagePack parse failure", ex);
}
}); Prevention
- Ensure every hub argument type is MessagePack-serializable on both ends.
- Register custom MessagePack formatters symmetrically or not at all.
- Fall back to JSON protocol temporarily to isolate MessagePack-specific corruption.
When it happens
Trigger: The MessagePack payload is structurally invalid: wrong array arity, unknown message-type int, missing fields for the declared message type, or a stream that ended mid-message after the length header passed.
Common situations: Protocol version mismatch (server sends a newer message shape the client cannot unpack); MessagePack library version skew; payload corrupted in transit but the length header happened to be valid; a server hub argument type that has no symmetric MessagePack representation on the client.
Related errors
- Unexpected message type
- Error reading JSON.
- Error reading length header.
- Error writing MessagePack data.
- Invalid invocation result kind.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/fe35e90eda2cc287.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/MessagePackHubProtocol.java:137
// Make sure that we actually read the right number of bytes
int readBytes = (int) unpacker.getTotalReadBytes();
if (readBytes != length) {
// Check what the last message was
// If it was an invocation binding failure, we have to correct the position of the buffer
if (hubMessages.get(hubMessages.size() - 1).getMessageType() == HubMessageType.INVOCATION_BINDING_FAILURE) {
// Cast to a Buffer to avoid the Java 9+ behavior where ByteBuffer.position(int) overrides Buffer.position(int),
// Returning a ByteBuffer rather than a Buffer. This causes issues on Android - see https://github.com/dotnet/aspnetcore/pull/26614
((Buffer) payload).position(payload.position() + (length - readBytes));
} else {
throw new RuntimeException(String.format("MessagePack message was length %d but claimed to be length %d.", readBytes, length));
}
}
unpacker.close();
// Cast to a Buffer to avoid the Java 9+ behavior where ByteBuffer.position(int) overrides Buffer.position(int),
// Returning a ByteBuffer rather than a Buffer. This causes issues on Android - see https://github.com/dotnet/aspnetcore/pull/26614
((Buffer) payload).position(payload.position() + readBytes);
} catch (MessagePackException | IOException ex) {
throw new RuntimeException("Error reading MessagePack data.", ex);
}
}
return hubMessages;
}
@Override
public ByteBuffer writeMessage(HubMessage hubMessage) {
HubMessageType messageType = hubMessage.getMessageType();
try {
byte[] message;
switch (messageType) {
case INVOCATION:
message = writeInvocationMessage((InvocationMessage) hubMessage);
break;
case STREAM_ITEM:
message = writeStreamItemMessage((StreamItem) hubMessage);
break;View on GitHub (pinned to 3600ca084e)