apache/shardingsphere · warning · IllegalArgumentException

BLR is too short: %s

Error message

BLR is too short: %s

What it means

UnsupportedSQLOperationException thrown by PostgreSQLComDescribeExecutor when a Describe message's type byte is neither 'S' (prepared statement) nor 'P' (portal). Per the extended protocol, Describe must name one of those two objects; any other type byte reaches the default branch and the message embeds the offending type.

Source

Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdParseBatchBlr.java:75

        validateSupported(result.fields);
        return result;
    }
    
    /**
     * Parse a BLR message buffer into its message format for codec framing only, without semantic support validation.
     *
     * <p>Used by the packet codec to split a coalesced {@code BATCH_CREATE + BATCH_MSG} frame. Semantically unsupported
     * but structurally valid fields (such as BLOB) are returned as descriptors instead of being rejected here, so that the
     * rejection happens later on the command/error path rather than as a codec-level channel close.</p>
     *
     * @param blr BLR buffer
     * @param blrLength BLR length
     * @return parsed message format
     * @throws IllegalArgumentException when BLR format is structurally invalid
     */
    public static FirebirdParseBatchBlr parseForFraming(final ByteBuf blr, final int blrLength) {
        if (blrLength < HEADER_LENGTH) {
            throw new IllegalArgumentException("BLR is too short: " + blrLength);
        }
        ByteBuf buffer = blr.duplicate();
        final int startReaderIndex = buffer.readerIndex();
        int version = buffer.readUnsignedByte();
        if (BlrConstants.blr_version4 != version && BlrConstants.blr_version5 != version) {
            throw new IllegalArgumentException("Unsupported BLR version: " + version);
        }
        if (BlrConstants.blr_begin != buffer.readUnsignedByte()) {
            throw new IllegalArgumentException("Expected blr_begin");
        }
        if (BlrConstants.blr_message != buffer.readUnsignedByte()) {
            throw new IllegalArgumentException("Expected blr_message");
        }
        buffer.skipBytes(1);
        FirebirdParseBatchBlr result = parseFormat(buffer);
        validateTermination(buffer, startReaderIndex, blrLength);
        return result;
    }

View on GitHub (pinned to e952770a21)

Solutions

  1. Send Describe with type 'S' to describe a prepared statement or 'P' to describe a portal, following the PostgreSQL protocol.
  2. Add client-side validation of the message type byte before writing Describe to the socket.
  3. Upgrade/patch the driver if it is responsible for emitting the bad type; check its changelog for extended-protocol fixes.
  4. Capture the wire bytes to rule out in-transit corruption when the client claims to send a valid type.

Example fix

// before (custom client)
describe(type='T', name="stmt1");

// after
describe(type='S', name="stmt1"); // statement; use 'P' for a portal
Defensive patterns

Strategy: validation

Validate before calling

// Custom client: validate Describe message before sending
byte type = describeTarget;
if (type != 'S' && type != 'P') {
    throw new IllegalArgumentException("Invalid Describe type byte: " + (char) type);
}
sendDescribe(type, name);

Prevention

When it happens

Trigger: Sending a Describe message with an invalid type byte — custom wire-protocol clients, corrupted packets, or driver bugs — e.g. describing with type 'Q' or 0x00.

Common situations: Hand-rolled extended-protocol implementations that confuse the Describe type with Close/Execute fields; fuzzing tools; stream corruption through proxies/LBs; driver regressions that marshal the type byte incorrectly.

Related errors


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