apache/shardingsphere · error · IllegalArgumentException

Expected blr_message

Error message

Expected blr_message

What it means

SQLFeatureNotSupportedException thrown by updateBlob(String, InputStream) on SQL federation ResultSets. The label+stream overload of updateBlob is final and throws in AbstractUnsupportedUpdateOperationSQLFederationResultSet, consistent with the class's contract: federation supports only read navigation of merged shard results. Any attempt to stream binary data into a named column of the current row is rejected at call time.

Source

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

     * @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()) {
            throw new IllegalArgumentException("Expected blr_eoc");
        }
        if (0 != remainingWithinBlr(buffer, startReaderIndex, blrLength)) {
            throw new IllegalArgumentException("Unexpected trailing bytes in BLR");
        }
    }

View on GitHub (pinned to e952770a21)

Solutions

  1. Issue UPDATE ... SET content = ? WHERE ... with ps.setBinaryStream instead
  2. Validate concurrency mode with rs.getConcurrency() before iterating when edits are planned
  3. Prevent federation for that query by rewriting SQL or adjusting federation settings

Example fix

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

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

Strategy: try-catch

Validate before calling

if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
    // label+stream updateBlob unsupported: use UPDATE + setBinaryStream
}

Try / catch

try {
    rs.updateBlob("content", inputStream);
} catch (SQLFeatureNotSupportedException e) {
    // federation cursor read-only; stream via PreparedStatement UPDATE
}

Prevention

When it happens

Trigger: Calling rs.updateBlob("content", inputStream) on a federated ResultSet before rs.updateRow(). Typical when upload code binds the BLOB column by its label.

Common situations: Attachment/file features that mutate rows while iterating a federated JOIN; persistence frameworks that map fields by label and call updateBlob during flush; environment change from direct driver to ShardingSphere proxy/JDBC.

Related errors


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