apache/shardingsphere · error · IllegalArgumentException
Expected blr_end
Error message
Expected blr_end
What it means
SQLFeatureNotSupportedException thrown by updateBlob(int, InputStream, long) on SQL federation ResultSets. The length-parameterized stream overload is one of the six updateBlob signatures, all final and throwing in AbstractUnsupportedUpdateOperationSQLFederationResultSet. Because federated ResultSets are read-only, the length hint never matters: the operation is refused before the stream is touched. This mirrors the JDBC 3-era pattern of bounded BLOB writes, which federation simply does not offer.
Source
Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdParseBatchBlr.java:97
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");
}
}
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");View on GitHub (pinned to e952770a21)
Solutions
- Use UPDATE with ps.setBinaryStream(index, stream, length) to preserve the bounded-write semantics
- Check getConcurrency() before planning cursor edits; fall back to DML when CONCUR_READ_ONLY
- Re-route the query away from federation if in-place edits are a hard requirement
Example fix
// before
rs.updateBlob(2, in, fileSize); // SQLFeatureNotSupportedException
// after
try (PreparedStatement ps = conn.prepareStatement("UPDATE files SET content = ? WHERE id = ?")) {
ps.setBinaryStream(1, in, fileSize);
ps.setLong(2, rs.getLong("id"));
ps.executeUpdate();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {
// bounded stream write unsupported: use UPDATE + setBinaryStream(1, in, length)
} Try / catch
try {
rs.updateBlob(columnIndex, inputStream, length);
} catch (SQLFeatureNotSupportedException e) {
// fall back to bounded setBinaryStream via DML
} Prevention
- Prefer modern length-less overloads via DML where possible
- Check concurrency before bounded writes
- Keep staged-file uploads on the DML path
When it happens
Trigger: Calling rs.updateBlob(columnIndex, inputStream, length) on a federation ResultSet then rs.updateRow(). Encountered in code that knows the exact byte count (e.g. a staged temp file) and uses the bounded API.
Common situations: Upload code migrated from older drivers where the bounded overload was the only stream option; batch importers writing known-size binaries in place; ShardingSphere introduced into an existing stack without a cursor-usage audit.
Related errors
- Expected blr_begin
- Expected blr_message
- Expected blr_eoc
- Unsupported BLR version: %s
- Expected blr_short NULL indicator, got: %s
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/d3f8f6b93d781d45.
Report an issue: GitHub.