{"record":{"id":"c980b721622440d5","repo":"apache/shardingsphere","slug":"truncated-batch-blob-segment-length","errorCode":null,"errorMessage":"Truncated batch BLOB segment length","messagePattern":"Truncated batch BLOB segment length","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":54,"sourceCode":"    \n    private final int blobHandle;\n    \n    private final int segmentLength;\n    \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.","sourceCodeStart":36,"sourceCodeEnd":72,"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#L36-L72","documentation":"Thrown while parsing a Firebird 'batch blob segments' command packet: the remaining buffer holds at least one byte (so the read loop continues) but fewer than the 2 bytes needed for a segment's unsigned-short length prefix. It means the client sent a malformed or truncated batch of BLOB segments. The library throws FirebirdProtocolException because it cannot safely continue deserializing the segment list.","triggerScenarios":"Constructing FirebirdBatchBlobSegmentsCommandPacket(FirebirdPacketPayload) where the buffered batch payload has a dangling 1-byte remainder after the last segment, or a client/proxy clipped the packet mid-length-prefix.","commonSituations":"Hand-written or buggy Firebird client, packet truncation by an intermediate proxy, or a protocol-version mismatch that changes the batch segment layout.","solutions":["Verify the raw bytes sent by the client against the Firebird wire protocol for batch blob segment upload; every segment must be a 2-byte LE length plus that many data bytes","Check for packet truncation between client and proxy (MTU/proxy framing bugs) and capture the frame with tcpdump/Wireshark","If implementing a Firebird client, ensure the final segment is fully written and no stray padding byte is appended","Report a bug to ShardingSphere if a stock Firebird driver reliably triggers this"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    new FirebirdBatchBlobSegmentsCommandPacket(payload);\n} catch (FirebirdProtocolException ex) {\n    // log payload.readableBytes() and the raw remaining buffer, then close the connection:\n    // a truncated batch cannot be resumed safely\n    throw new ProtocolViolationException(\"malformed batch blob segment list\", ex);\n}","preventionTips":["When building Firebird batch blob packets client-side, assert (2 + segment.length) sums exactly to the declared total batch length before sending","Add an integration test that round-trips a multi-segment blob through the proxy to catch framing regressions"],"tags":["firebird","protocol","blob","packet-parsing","truncated-data"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}