{"record":{"id":"ca25d589471b08b3","repo":"apache/shardingsphere","slug":"batch-blob-segment-declares-d-bytes-but-only-d","errorCode":null,"errorMessage":"Batch BLOB segment declares %d bytes, but only %d bytes remain","messagePattern":"Batch BLOB segment declares (.+?) bytes, but only (.+?) bytes remain","errorType":"exception","errorClass":"FirebirdProtocolException","httpStatus":null,"severity":"error","filePath":"database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/blob/FirebirdBatchBlobSegmentsCommandPacket.java","lineNumber":58,"sourceCode":"    \n    private final Collection<byte[]> segments;\n    \n    public FirebirdBatchBlobSegmentsCommandPacket(final FirebirdPacketPayload payload) {\n        payload.skipReserved(4);\n        blobHandle = payload.readBlobHandle();\n        segmentLength = payload.readInt4();\n        segments = readSegments(payload.readBuffer());\n    }\n    \n    private Collection<byte[]> readSegments(final ByteBuf buffer) {\n        Collection<byte[]> result = new LinkedList<>();\n        while (buffer.isReadable()) {\n            if (buffer.readableBytes() < Short.BYTES) {\n                throw new FirebirdProtocolException(\"Truncated batch BLOB segment length\");\n            }\n            int segmentLength = buffer.readUnsignedShortLE();\n            if (buffer.readableBytes() < segmentLength) {\n                throw new FirebirdProtocolException(\"Batch BLOB segment declares %d bytes, but only %d bytes remain\", segmentLength, buffer.readableBytes());\n            }\n            byte[] segmentData = new byte[segmentLength];\n            buffer.readBytes(segmentData);\n            result.add(segmentData);\n        }\n        return result;\n    }\n    \n    @Override\n    protected void write(final FirebirdPacketPayload payload) {\n    }\n    \n    /**\n     * Get length of packet.\n     *\n     * @param payload Firebird packet payload\n     * @return length of packet\n     */","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/blob/FirebirdBatchBlobSegmentsCommandPacket.java#L40-L76","documentation":"Thrown while parsing a Firebird batch BLOB segments packet: a 2-byte little-endian length prefix declares N bytes of segment data, but fewer than N bytes remain in the buffer. The declared size and actual remaining size are included in the message. The packet is internally inconsistent, so the segment list cannot be deserialized.","triggerScenarios":"Constructing FirebirdBatchBlobSegmentsCommandPacket where readSegments() reads a segmentLength via readUnsignedShortLE() larger than buffer.readableBytes() — e.g. a length prefix of 5000 with only 300 bytes left.","commonSituations":"Client bugs that write a wrong length prefix, packet truncation in transit, or endianness mistakes (writing big-endian lengths against a little-endian protocol) producing huge declared sizes.","solutions":["Compare the declared length in the message with the actual remaining bytes to confirm corruption vs. truncation","Fix the client/proxy that builds the batch so the 2-byte LE prefix exactly matches the segment payload size","Check for intermediaries (proxies, TLS terminators) that clip or coalesce frames incorrectly","Round-trip a known-good blob with the official Firebird driver and diff the bytes to locate the divergence"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    packet = new FirebirdBatchBlobSegmentsCommandPacket(payload);\n} catch (FirebirdProtocolException ex) {\n    // message already carries declared vs remaining bytes; fail the connection,\n    // do not attempt partial reads — segment data would be attributed to the wrong segment\n    abortConnection(ex);\n}","preventionTips":["Write length prefixes with writeShortLE matching the exact byte count you then write","Unit-test the packet builder with 0-byte, max-unsigned-short, and odd-remainder payloads"],"tags":["firebird","protocol","blob","packet-parsing","length-mismatch"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}