apache/shardingsphere · warning · IllegalStateException

Connection [%s] is not registered.

Error message

Connection [%s] is not registered.

What it means

UnsupportedSQLOperationException thrown by PostgreSQLComCloseExecutor when a Close message arrives whose type byte is neither PREPARED_STATEMENT ('S') nor PORTAL ('P'). The extended-protocol Close command must target one of those two named objects; anything else means a malformed or unexpected Close type and the switch falls to default.

Source

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

     *
     * @param connectionId connection ID
     */
    public void registerConnection(final int connectionId) {
        batchRegistry.put(connectionId, new ConcurrentHashMap<>());
    }
    
    /**
     * Register batch metadata.
     *
     * @param connectionId connection ID
     * @param statementId statement ID
     * @param batchStatement batch statement
     * @throws IllegalStateException if connection is not registered
     */
    public void registerBatchStatement(final int connectionId, final int statementId, final FirebirdBatchStatement batchStatement) {
        Map<Integer, FirebirdBatchStatement> statements = batchRegistry.get(connectionId);
        if (statements == null) {
            throw new IllegalStateException("Connection [" + connectionId + "] is not registered.");
        }
        statements.put(statementId, batchStatement);
    }
    
    /**
     * Get batch metadata.
     *
     * @param connectionId connection ID
     * @param statementId statement ID
     * @return batch statement or null if not found
     */
    public FirebirdBatchStatement getBatchStatement(final int connectionId, final int statementId) {
        Map<Integer, FirebirdBatchStatement> statements = batchRegistry.get(connectionId);
        if (statements == null) {
            return null;
        }
        return statements.get(statementId);
    }

View on GitHub (pinned to e952770a21)

Solutions

  1. Fix the client to send Close with type 'S' (close prepared statement) or 'P' (close portal) per the PostgreSQL Frontend/Backend protocol.
  2. If using a custom driver, validate the Close message construction against the protocol spec before sending.
  3. Upgrade or patch the client driver if a released version emits the malformed Close.
  4. Inspect the wire bytes (protocol trace) to confirm whether the type byte is corrupted in transit.

Example fix

// before (custom client): wrong type byte
closeMessage(type='X', name=portalName);

// after
closeMessage(type='P', name=portalName); // or 'S' for prepared statement
Defensive patterns

Strategy: validation

Validate before calling

// Custom client: validate Close message before sending
byte type = closeTarget; // must be 'S' or 'P'
if (type != 'S' && type != 'P') {
    throw new IllegalArgumentException("Invalid Close type byte: " + (char) type);
}
sendClose(type, name);

Prevention

When it happens

Trigger: Sending a Close message with a type byte other than 'S' or 'P' — typically a hand-written client, a corrupted stream, or a driver bug constructing the Close packet incorrectly.

Common situations: Custom PostgreSQL wire-protocol implementations; protocol fuzzing; a driver version that emits an invalid Close type; byte-level corruption from middleware/LB between client and proxy.

Related errors


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