apache/shardingsphere · error · IllegalArgumentException

Unsupported BLR version: %s

Error message

Unsupported BLR version: %s

What it means

SQLFeatureNotSupportedException thrown by updateBlob(String, Blob) on SQL federation ResultSets. The column-label variant of updateBlob is final and throws in AbstractUnsupportedUpdateOperationSQLFederationResultSet just like the index variant. SQL federation merges shard results into a read-only cursor, so attaching a Blob to a named column of the current row is categorically unsupported.

Source

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

     *
     * <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;
    }
    
    private static void validateTermination(final ByteBuf buffer, final int startReaderIndex, final int blrLength) {
        if (remainingWithinBlr(buffer, startReaderIndex, blrLength) < 1 || BlrConstants.blr_end != buffer.readUnsignedByte()) {
            throw new IllegalArgumentException("Expected blr_end");
        }
        if (remainingWithinBlr(buffer, startReaderIndex, blrLength) < 1 || BlrConstants.blr_eoc != buffer.readUnsignedByte()) {

View on GitHub (pinned to e952770a21)

Solutions

  1. Replace with an UPDATE statement using setBlob or setBinaryStream on PreparedStatement
  2. Branch on rs.getConcurrency() before update attempts; CONCUR_READ_ONLY means statement-based DML only
  3. Avoid federation for binary-write workloads by adjusting query or federation configuration

Example fix

// before
rs.updateBlob("content", blob); // SQLFeatureNotSupportedException

// after
try (PreparedStatement ps = conn.prepareStatement("UPDATE files SET content = ? WHERE id = ?")) {
    ps.setBlob(1, blob);
    ps.setLong(2, rs.getLong("id"));
    ps.executeUpdate();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
    // label-based updateBlob unsupported: use UPDATE + setBlob
}

Try / catch

try {
    rs.updateBlob("content", blob);
} catch (SQLFeatureNotSupportedException e) {
    // fall back to UPDATE DML keyed by primary key
}

Prevention

When it happens

Trigger: Calling rs.updateBlob("content", blob) on a federated ResultSet then rs.updateRow(). Common in label-based persistence helpers handling binary attachments.

Common situations: Document-management code updating BLOB columns in place; apps previously running on drivers with CONCUR_UPDATABLE support moved behind ShardingSphere; federation newly triggered by a cross-shard JOIN in a previously simple query.

Related errors


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