apache/shardingsphere · error · FirebirdProtocolException

Invalid batch parameter length for tag %d: %d

Error message

Invalid batch parameter length for tag %d: %d

What it means

FirebirdProtocolException from ensureClumpletValueReadable: a batch parameter clumplet declares a value length that is negative or larger than the bytes actually remaining in the buffer. The declared length cannot be satisfied, so the clumplet stream is corrupt.

Source

Thrown at proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutor.java:164

            }
            // return new BatchParameters(version, bufferSize, recordCounts, multiError, blobPolicy);
            return new BatchParameters(version, bufferSize, recordCounts, multiError);
        }
        
        private static long getBufferSize(final int requestedBufferSize) {
            long result = Integer.toUnsignedLong(requestedBufferSize);
            return 0L == result ? MAX_BUFFER_SIZE : Math.min(result, MAX_BUFFER_SIZE);
        }
        
        private static void ensureClumpletHeaderReadable(final ByteBuf reader) {
            if (reader.readableBytes() < 1 + WIDE_CLUMPLET_LENGTH_SIZE) {
                throw new FirebirdProtocolException("Invalid batch parameters buffer");
            }
        }
        
        private static void ensureClumpletValueReadable(final ByteBuf reader, final int tag, final int valueLength) {
            if (valueLength < 0 || valueLength > reader.readableBytes()) {
                throw new FirebirdProtocolException("Invalid batch parameter length for tag %d: %d", tag, valueLength);
            }
        }
        
        private static int readIntegerValue(final ByteBuf reader, final int tag, final int valueLength) {
            if (INTEGER_VALUE_LENGTH != valueLength) {
                throw new FirebirdProtocolException("Invalid batch parameter integer length for tag %d: %d", tag, valueLength);
            }
            return reader.readIntLE();
        }
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Write clumplet value lengths as 4-byte LITTLE-ENDIAN integers counting only the value bytes.
  2. Ensure total buffer length equals the sum of all clumplet headers plus declared value lengths.
  3. Compare the generated bytes against a capture of a working Firebird client doing the same operation.
Defensive patterns

Strategy: try-catch

Try / catch

catch (SQLException e) {
    if (e.getMessage().contains("Invalid batch parameter length")) { throw new IllegalStateException("client clumplet length bug (LE/overrun)", e); }
    throw e;
}

Prevention

When it happens

Trigger: BatchParameters.parse() reads valueLength = reader.readIntLE() and checks valueLength < 0 || valueLength > reader.readableBytes(); a client-sent length field pointing past the end of the buffer (or a sign-bit-set length read as negative) triggers the throw with the offending tag and length in the message.

Common situations: big-endian vs little-endian confusion when hand-writing the length (proxy reads readIntLE); length includes the header itself instead of only the value; buffer truncated mid-clumplet.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/baaa474e3d963f75. Report an issue: GitHub.