apache/shardingsphere · error · FirebirdProtocolException
Batch BLOB segment declares %d bytes, but only %d bytes rema
Error message
Batch BLOB segment declares %d bytes, but only %d bytes remain
What it means
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.
Source
Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/blob/FirebirdBatchBlobSegmentsCommandPacket.java:58
private final Collection<byte[]> segments;
public FirebirdBatchBlobSegmentsCommandPacket(final FirebirdPacketPayload payload) {
payload.skipReserved(4);
blobHandle = payload.readBlobHandle();
segmentLength = payload.readInt4();
segments = readSegments(payload.readBuffer());
}
private Collection<byte[]> readSegments(final ByteBuf buffer) {
Collection<byte[]> result = new LinkedList<>();
while (buffer.isReadable()) {
if (buffer.readableBytes() < Short.BYTES) {
throw new FirebirdProtocolException("Truncated batch BLOB segment length");
}
int segmentLength = buffer.readUnsignedShortLE();
if (buffer.readableBytes() < segmentLength) {
throw new FirebirdProtocolException("Batch BLOB segment declares %d bytes, but only %d bytes remain", segmentLength, buffer.readableBytes());
}
byte[] segmentData = new byte[segmentLength];
buffer.readBytes(segmentData);
result.add(segmentData);
}
return result;
}
@Override
protected void write(final FirebirdPacketPayload payload) {
}
/**
* Get length of packet.
*
* @param payload Firebird packet payload
* @return length of packet
*/View on GitHub (pinned to e952770a21)
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
Defensive patterns
Strategy: try-catch
Try / catch
try {
packet = new FirebirdBatchBlobSegmentsCommandPacket(payload);
} catch (FirebirdProtocolException ex) {
// message already carries declared vs remaining bytes; fail the connection,
// do not attempt partial reads — segment data would be attributed to the wrong segment
abortConnection(ex);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Truncated batch BLOB segment length
- Can not locate agent jar file by URL `%s`.
- 6
- Unknown blob information request type %d
- Unknown common information request type %d
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/ca25d589471b08b3.
Report an issue: GitHub.