{"record":{"id":"c7e0c53c072fbddd","repo":"dotnet/aspnetcore","slug":"error-reading-length-header","errorCode":null,"errorMessage":"Error reading length header.","messagePattern":"Error reading length header\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/MessagePackHubProtocol.java","lineNumber":86,"sourceCode":"         // MessagePack library can't handle read-only ByteBuffer - copy into an array-backed ByteBuffer if this is the case\n        if (payload.isReadOnly()) {\n            byte[] payloadBytes = new byte[payload.remaining()];\n            payload.get(payloadBytes, 0, payloadBytes.length);\n            payload = ByteBuffer.wrap(payloadBytes);\n        }\n\n        List<HubMessage> hubMessages = new ArrayList<>();\n\n        while (payload.hasRemaining()) {\n            int length;\n            try {\n                length = Utils.readLengthHeader(payload);\n                // Throw if remaining buffer is shorter than length header\n                if (payload.remaining() < length) {\n                    throw new RuntimeException(String.format(\"MessagePack message was length %d but claimed to be length %d.\", payload.remaining(), length));\n                }\n            } catch (IOException ex) {\n                throw new RuntimeException(\"Error reading length header.\", ex);\n            }\n            // Instantiate MessageUnpacker\n            try(MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(payload)) {\n\n                int itemCount = unpacker.unpackArrayHeader();\n                HubMessageType messageType = HubMessageType.values()[unpacker.unpackInt() - 1];\n\n                switch (messageType) {\n                    case INVOCATION:\n                        hubMessages.add(createInvocationMessage(unpacker, binder, itemCount, payload));\n                        break;\n                    case STREAM_ITEM:\n                        hubMessages.add(createStreamItemMessage(unpacker, binder, payload));\n                        break;\n                    case COMPLETION:\n                        hubMessages.add(createCompletionMessage(unpacker, binder, payload));\n                        break;\n                    case STREAM_INVOCATION:","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/MessagePackHubProtocol.java#L68-L104","documentation":"Utils.readLengthHeader reads the length prefix and may throw IOException for malformed prefix bytes or insufficient data. MessagePackHubProtocol catches that IOException and wraps it as a RuntimeException with 'Error reading length header.' This is the entry-point parse failure: the framing could not even be read.","triggerScenarios":"The first bytes of a MessagePack frame are not a valid length-header encoding, or the buffer has fewer than the header byte count; the protocol received binary data that is not MessagePack at all.","commonSituations":"Hub endpoint configured with JSON on the server but the client selected MessagePack (or vice-versa); a custom subprotocol mismatched the wire format; binary corruption from a transport layer; a stale buffer reused after a reconnect.","solutions":["Confirm both server and client negotiate the same protocol - if the server only has JSON, do not call withHubProtocol(MessagePackHubProtocol).","On the server register AddMessagePackProtocol() if you intend to use MessagePack; on the client ensure the negotiated protocol is MessagePack.","Inspect the first few bytes of the failing frame to confirm they look like a MessagePack length header (varint)."],"exampleFix":"// before - client forces MessagePack but server has only JSON\nHubConnectionBuilder.create(url)\n    .withHubProtocol(new MessagePackHubProtocol())\n    .build();\n\n// after - register MessagePack on the server too\n// server: services.AddSignalR().AddMessagePackProtocol();\nHubConnectionBuilder.create(url)\n    .withHubProtocol(new MessagePackHubProtocol())\n    .build();","handlingStrategy":"validation","validationCode":"// Confirm the negotiated protocol matches what you configured.\n// After start(), inspect handshake result / server response to ensure\n// 'messagepack' was accepted (not silently falling back to JSON).\n// Pre-flight: hit /negotiate and check that the server lists messagepack.\nSet<String> protocols = fetchNegotiate(url).availableTransports\n    .stream().flatMap(t -> t.getTransferFormats().stream())\n    .collect(toSet()); // adjust to your server's negotiate shape\nif (!protocols.contains(\"messagepack\")) {\n  throw new IllegalStateException(\"Server does not offer MessagePack\");\n}","typeGuard":null,"tryCatchPattern":"hub.onClosed(ex -> {\n  if (ex != null && ex.getMessage().contains(\"Error reading length header\")) {\n    // protocol mismatch; verify AddMessagePackProtocol on server\n  }\n});","preventionTips":["Register AddMessagePackProtocol() on the server whenever the client uses MessagePackHubProtocol.","Negotiate smoke-test that the server advertises the messagepack protocol.","Do not mix a custom subprotocol that changes the wire format."],"tags":["signalr","java","messagepack","protocol","configuration"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}