dotnet/aspnetcore · error · RuntimeException

Error writing MessagePack data.

Error message

Error writing MessagePack data.

What it means

Wraps MessagePackException/IOException thrown while serializing an outbound message through the Jackson MessagePack ObjectMapper/packer. It is usually caused by an argument type Jackson cannot serialize — no default constructor, circular references, an unsupported type like raw ByteBuffer, or a missing date/time module.

Source

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

                default:
                    throw new RuntimeException(String.format("Unexpected message type: %d", messageType.value));
            }
            int length = message.length;
            List<Byte> header = Utils.getLengthHeader(length);
            byte[] messageWithHeader = new byte[header.size() + length];
            int headerSize = header.size();

            // Write the length header, then all of the bytes of the original message
            for (int i = 0; i < headerSize; i++) {
                messageWithHeader[i] = header.get(i);
            }
            for (int i = 0; i < length; i++) {
                messageWithHeader[i + headerSize] = message[i];
            }

            return ByteBuffer.wrap(messageWithHeader);
        } catch (MessagePackException | IOException ex) {
            throw new RuntimeException("Error writing MessagePack data.", ex);
        }
    }

    private HubMessage createInvocationMessage(MessageUnpacker unpacker, InvocationBinder binder, int itemCount, ByteBuffer payload) throws IOException {
        Map<String, String> headers = readHeaders(unpacker);

        // invocationId may be nil
        String invocationId = null;
        if (!unpacker.tryUnpackNil()) {
            invocationId = unpacker.unpackString();
        }

        // For MsgPack, we represent an empty invocation ID as an empty string,
        // so we need to normalize that to "null", which is what indicates a non-blocking invocation.
        if (invocationId == null || invocationId.isEmpty()) {
            invocationId = null;
        }

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Ensure arguments sent to hub methods are plain POJOs serializable by Jackson.
  2. Register jackson-datatype-jsr310 (and any other needed modules) if sending date/time types.
  3. Map framework/IO types to simple DTOs (e.g. byte[] instead of ByteBuffer) before sending.

Example fix

// before
hubConnection.send("Upload", someByteBuffer);

// after
hubConnection.send("Upload", someByteBuffer.array());
Defensive patterns

Strategy: validation

Validate before calling

// Java - only send Jackson-serializable POJOs
static boolean isLikelySerializable(Object o) {
    return o == null
        || o instanceof String || o instanceof Number || o instanceof Boolean
        || o instanceof java.util.Collection || o instanceof java.util.Map
        || (o.getClass().isArray() && !o.getClass().getComponentType().getName().contains("Buffer"));
}

Try / catch

// Java
try {
    hubConnection.send("Method", arg).blockingAwait();
} catch (RuntimeException ex) {
    if (ex.getMessage() != null && ex.getMessage().contains("writing MessagePack")) {
        // replace unserializable arg (ByteBuffer, IO type, etc.) with a plain DTO
    }
}

Prevention

When it happens

Trigger: Passing an object to hubConnection.invoke/send that the MessagePack ObjectMapper cannot serialize; sending IO/framework types or POJOs without accessible constructors/getters.

Common situations: Sending a Java object lacking a no-arg constructor or getters; including unserializable fields (ByteBuffer, InputStream, lambdas); sending java.time types without jackson-datatype-jsr310 registered.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/e772f0442dafd4ee. Report an issue: GitHub.