{"record":{"id":"6715761ea4f81605","repo":"dotnet/aspnetcore","slug":"the-length-header-was-incomplete","errorCode":null,"errorMessage":"The length header was incomplete","messagePattern":"The length header was incomplete","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/Utils.java","lineNumber":37,"sourceCode":"        // VarInt: 0x35 - %00110101 - the most significant bit is 0 so the value is %x0110101 i.e. 0x35 (53)\n        // VarInt: 0x80 0x25 - %10000000 %00101001 - the most significant bit of the first byte is 1 so the\n        // remaining bits (%x0000000) are the lowest bits of the value. The most significant bit of the second\n        // byte is 0 meaning this is last byte of the VarInt. The actual value bits (%x0101001) need to be\n        // prepended to the bits we already read so the values is %01010010000000 i.e. 0x1480 (5248)\n        // We support payloads up to 2GB so the biggest number we support is 7fffffff which when encoded as\n        // VarInt is 0xFF 0xFF 0xFF 0xFF 0x07 - hence the maximum length prefix is 5 bytes.\n        \n        int length = 0;\n        int numBytes = 0;\n        int maxLength = 5;\n        byte curr;\n        \n        do {\n            // If we run out of bytes before we finish reading the length header, the message is malformed\n            if (buffer.hasRemaining()) {\n                curr = buffer.get();\n            } else {\n                throw new RuntimeException(\"The length header was incomplete\");\n            }\n            length = length | (curr & (byte) 0x7f) << (numBytes * 7);\n            numBytes++;\n        } while (numBytes < maxLength && (curr & (byte) 0x80) != 0);\n        \n        // Max header length is 5, and the maximum value of the 5th byte is 0x07\n        if ((curr & (byte) 0x80) != 0 || (numBytes == maxLength && curr > (byte) 0x07)) {\n            throw new RuntimeException(\"Messages over 2GB in size are not supported\");\n        }\n        \n        return length;\n    }\n    \n    public static ArrayList<Byte> getLengthHeader(int length) {\n        // This code writes length prefix of the message as a VarInt. Read the comment in\n        // the readLengthHeader for details.\n        \n        ArrayList<Byte> header = new ArrayList<Byte>();","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/Utils.java#L19-L55","documentation":"readLengthHeader reads the varint prefix byte-by-byte; if the buffer runs out of bytes before a terminating varint byte (MSB clear) is reached, the header is incomplete and the message cannot be framed.","triggerScenarios":"Buffer ends mid-varint; a payload containing only a partial length prefix; transport delivers a fragment rather than a complete frame.","commonSituations":"Truncated transport read; incorrect frame reassembly; connection drop mid-frame; proxy splitting the stream.","solutions":["Ensure the transport reassembles complete frames before handing them to the protocol.","Verify the peer is not sending partial frames.","Check for framing/offset bugs if you layer a custom transport."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Java\ntry {\n    hubConnection.start().blockingAwait();\n} catch (RuntimeException ex) {\n    if (ex.getMessage() != null && ex.getMessage().contains(\"length header was incomplete\")) {\n    }\n}","preventionTips":["Make the transport reassemble complete frames before delivery.","Verify the peer is not sending partial frames.","Handle connection close to avoid parsing fragments."],"tags":["signalr","messagepack","framing","protocol"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}