apache/shardingsphere · error · IllegalArgumentException

Unexpected trailing bytes in BLR

Error message

Unexpected trailing bytes in BLR

What it means

SQLFeatureNotSupportedException thrown by updateClob(int, Clob) on SQL federation ResultSets. AbstractUnsupportedUpdateOperationSQLFederationResultSet declares all six updateClob overloads final and throwing: federated ResultSets are CONCUR_READ_ONLY merged views, so writing a java.sql.Clob into a column of the current row is unsupported. The exception is thrown synchronously; no part of the Clob is transferred.

Source

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

        }
        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");
        }
    }
    
    private static int remainingWithinBlr(final ByteBuf buffer, final int startReaderIndex, final int blrLength) {
        return blrLength - (buffer.readerIndex() - startReaderIndex);
    }
    
    private static void validateSupported(final List<FirebirdBatchColumnDescriptor> fields) {
        for (FirebirdBatchColumnDescriptor each : fields) {
            if (FirebirdBinaryColumnType.BLOB == each.getType()) {
                // TODO Implement BATCH_REGBLOB, BATCH_BLOB_STREAM and BATCH_SET_BPB before accepting BLOB fields.
                throw new FirebirdProtocolException("BLOB fields are not supported in Firebird batch operations");
            }
        }
    }
    
    private static FirebirdParseBatchBlr parseFormat(final ByteBuf buffer) {
        int count = buffer.readUnsignedByte();

View on GitHub (pinned to e952770a21)

Solutions

  1. Write the CLOB with an UPDATE statement using ps.setClob or ps.setCharacterStream, keyed by primary key
  2. For very large text prefer streaming via setCharacterStream to avoid materializing the whole Clob
  3. Branch on rs.getConcurrency() before any updateXxx call and use DML for read-only cursors
  4. Avoid federated execution for statements whose results must be editable

Example fix

// before
rs.updateClob(3, clob); // SQLFeatureNotSupportedException
rs.updateRow();

// after
try (PreparedStatement ps = conn.prepareStatement("UPDATE docs SET body = ? WHERE id = ?")) {
    ps.setClob(1, clob);
    ps.setLong(2, rs.getLong("id"));
    ps.executeUpdate();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {
    // CLOB write unsupported: use UPDATE + setClob instead
}

Try / catch

try {
    rs.updateClob(columnIndex, clob);
} catch (SQLFeatureNotSupportedException e) {
    // federation ResultSet read-only; store CLOB via UPDATE DML
}

Prevention

When it happens

Trigger: Calling rs.updateClob(columnIndex, clob) on a federation ResultSet followed by rs.updateRow(). Typical in text/document features that store large character data in CLOB columns via the cursor API.

Common situations: Document or report storage code written against a driver that supported updatable ResultSets; ShardingSphere JDBC/proxy adopted underneath an existing app; cross-shard JOINs newly routed through federation where cursor updates previously worked.

Related errors


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