dotnet/aspnetcore · error · RuntimeException

MessagePack message was length

Error message

MessagePack message was length %d but claimed to be length %d.

What it means

In MessagePackHubProtocol.parseMessages, after reading the length-prefix header the code checks payload.remaining() >= length. If the remaining bytes in the buffer are fewer than the length the header claimed, the message is truncated/corrupt and the throw fires with (remaining, claimed). This is a wire-format integrity check.

Solutions

  1. Increase the transport's max message size on both server (MaximumReceiveMessageSize) and client so frames are not split unexpectedly.
  2. Ensure the server and client use the same MessagePack protocol (both default or both custom).
  3. Verify intermediate proxies/load balancers preserve WebSocket frame integrity; bypass them to isolate.
  4. Capture a packet/WebSocket-frame trace to confirm the length header matches the payload.

Example fix

// before - server sends large messages, default caps truncate
services.AddSignalR()
    .AddMessagePackProtocol();

// after - raise caps on both ends
services.AddSignalR(o => o.MaximumReceiveMessageSize = 256 * 1024)
    .AddMessagePackProtocol();
// client side, ensure the transport buffer can hold the frame
Defensive patterns

Strategy: try-catch

Try / catch

hub.onClosed(ex -> {
  if (ex != null && ex.getMessage().contains("MessagePack message was length")) {
    // framing integrity failure; raise MaximumReceiveMessageSize and reconnect
    log.error("MessagePack frame truncated; check server/client size caps");
  }
});

Prevention

When it happens

Trigger: Receiving a MessagePack frame whose prefix declares more bytes than the transport actually delivered: truncated TCP/WebSocket frame, buffer underflow from a partial read, or a server/client MessagePack version mismatch producing a bad header.

Common situations: Network layer truncating large frames; a buggy proxy not honoring WebSocket frame boundaries; mixed MessagePack libraries on server vs client disagreeing on the length-header encoding; partial buffer handed to parseMessages.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/e31d5fb5817032ee. Report an issue: GitHub.

Appendix: source

Thrown at src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/MessagePackHubProtocol.java:83

            return null;
        }

         // MessagePack library can't handle read-only ByteBuffer - copy into an array-backed ByteBuffer if this is the case
        if (payload.isReadOnly()) {
            byte[] payloadBytes = new byte[payload.remaining()];
            payload.get(payloadBytes, 0, payloadBytes.length);
            payload = ByteBuffer.wrap(payloadBytes);
        }

        List<HubMessage> hubMessages = new ArrayList<>();

        while (payload.hasRemaining()) {
            int length;
            try {
                length = Utils.readLengthHeader(payload);
                // Throw if remaining buffer is shorter than length header
                if (payload.remaining() < length) {
                    throw new RuntimeException(String.format("MessagePack message was length %d but claimed to be length %d.", payload.remaining(), length));
                }
            } catch (IOException ex) {
                throw new RuntimeException("Error reading length header.", ex);
            }
            // Instantiate MessageUnpacker
            try(MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(payload)) {

                int itemCount = unpacker.unpackArrayHeader();
                HubMessageType messageType = HubMessageType.values()[unpacker.unpackInt() - 1];

                switch (messageType) {
                    case INVOCATION:
                        hubMessages.add(createInvocationMessage(unpacker, binder, itemCount, payload));
                        break;
                    case STREAM_ITEM:
                        hubMessages.add(createStreamItemMessage(unpacker, binder, payload));
                        break;
                    case COMPLETION:

View on GitHub (pinned to 3600ca084e)