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
- Replace with an UPDATE statement using setBlob or setBinaryStream on PreparedStatement
- Branch on rs.getConcurrency() before update attempts; CONCUR_READ_ONLY means statement-based DML only
- 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
- Refactor attachment uploads to DML writes
- Audit binary-write paths when adopting ShardingSphere
- Keep editable result sets out of federated queries
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
- Expected blr_begin
- Expected blr_message
- Expected blr_end
- Expected blr_eoc
- Unexpected trailing bytes in BLR
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/f3a3dacb10d071e2.
Report an issue: GitHub.