apache/shardingsphere · error · FirebirdProtocolException
Unknown DSQL option type %d
Error message
Unknown DSQL option type %d
What it means
FirebirdProtocolException thrown by FirebirdFreeStatementCommandExecutor when the option int in a FREE STATEMENT packet is not one of DROP, UNPREPARE, or CLOSE. Unknown option values mean the packet is malformed or the client uses a DSQL free option this proxy does not implement.
Source
Thrown at proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/free/FirebirdFreeStatementCommandExecutor.java:57
private final FirebirdFreeStatementPacket packet;
private final ConnectionSession connectionSession;
@Override
public Collection<DatabasePacket> execute() throws SQLException {
switch (packet.getOption()) {
case FirebirdFreeStatementPacket.DROP:
case FirebirdFreeStatementPacket.UNPREPARE:
connectionSession.getServerPreparedStatementRegistry().removePreparedStatement(packet.getStatementId());
FirebirdBatchRegistry.getInstance().unregisterBatchStatement(connectionSession.getConnectionId(), packet.getStatementId());
FirebirdStatementResourceCleaner.clean(connectionSession, packet.getStatementId(), true);
break;
case FirebirdFreeStatementPacket.CLOSE:
FirebirdStatementResourceCleaner.clean(connectionSession, packet.getStatementId(), false);
break;
default:
throw new FirebirdProtocolException("Unknown DSQL option type %d", packet.getOption());
}
return Collections.singleton(new FirebirdGenericResponsePacket());
}
}
View on GitHub (pinned to e952770a21)
Solutions
- Send only the DROP, UNPREPARE or CLOSE option constants exactly as the Firebird DSQL API defines them.
- If the option is a bitmask in your client, mask to the single supported option rather than OR-ing flags.
- Verify overall packet layout (option int position) against the Firebird wire protocol when hand-encoding.
Defensive patterns
Strategy: validation
Validate before calling
static final int DSQL_DROP = 2, DSQL_UNPREPARE = 4, DSQL_CLOSE = 1;
if (!Set.of(DSQL_DROP, DSQL_UNPREPARE, DSQL_CLOSE).contains(option)) throw new IllegalArgumentException("bad free option");
sendFreeStatement(stmtHandle, option); Try / catch
catch (SQLException e) {
if (e.getMessage().contains("Unknown DSQL option")) { sendFreeStatement(stmtHandle, DSQL_DROP); } else throw e;
} Prevention
- Send single option constants, never OR-ed masks.
- Prefer DROP (frees everything) unless you need CLOSE semantics.
When it happens
Trigger: switch (packet.getOption()) hits default; only FirebirdFreeStatementPacket.DROP, .UNPREPARE (both remove the prepared statement and unregister any batch) and .CLOSE (resource cleanup only) are accepted.
Common situations: hand-written clients sending a raw Firebird DSQL_free option bitmask that includes unhandled bits; newer client sending an option constant added after the proxy implementation; packet misalignment making a different field land in the option slot.
Related errors
- Unknown statement info request type %d
- Unknown statement info request type %d
- Can not locate agent jar file by URL `%s`.
- 6
- Truncated batch BLOB segment length
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/cf9d48eb9b34db3b.
Report an issue: GitHub.