apache/shardingsphere · error · MissingRequiredPrivilegeException

6

6

Error message

Missing required privilege(s) `%s`

What it means

MySQL error 1105 (ER_UNKNOWN_ERROR) thrown by MySQLServerPreparedStatement.getLongDataIndexes() when a parameter accumulated via COM_STMT_SEND_LONG_DATA exceeded the connection's max_allowed_packet size. During accumulation the flag longDataTooLarge is set instead of failing immediately; the error surfaces later, when the prepared statement is next executed or described and the long-data indexes are requested as a SQLException with XOpenSQLState.GENERAL_ERROR.

Source

Thrown at database/connector/dialect/mysql/src/main/java/org/apache/shardingsphere/database/connector/mysql/checker/MySQLDatabasePrivilegeChecker.java:84

        } catch (final SQLException ex) {
            throw new CheckDatabaseEnvironmentFailedException(ex);
        }
    }
    
    private void checkPrivilege(final Connection connection, final PrivilegeCheckType privilegeCheckType) {
        try (
                PreparedStatement preparedStatement = connection.prepareStatement(SHOW_GRANTS_SQL);
                ResultSet resultSet = preparedStatement.executeQuery()) {
            while (resultSet.next()) {
                String privilege = resultSet.getString(1).toUpperCase();
                if (matchPrivileges(privilege, getRequiredPrivileges(connection, privilegeCheckType))) {
                    return;
                }
            }
        } catch (final SQLException ex) {
            throw new CheckDatabaseEnvironmentFailedException(ex);
        }
        throw new MissingRequiredPrivilegeException(REQUIRED_PRIVILEGES_FOR_MESSAGE.get(privilegeCheckType));
    }
    
    private String[][] getRequiredPrivileges(final Connection connection, final PrivilegeCheckType privilegeCheckType) throws SQLException {
        switch (privilegeCheckType) {
            case PIPELINE:
                return PIPELINE_REQUIRED_PRIVILEGES;
            case SELECT:
                return getSelectRequiredPrivilege(connection);
            case XA:
                return XA_REQUIRED_PRIVILEGES;
            default:
                return new String[0][0];
        }
    }
    
    private String[][] getSelectRequiredPrivilege(final Connection connection) throws SQLException {
        String onCatalog = String.format("ON `%s`.*", connection.getCatalog().toUpperCase());
        return new String[][]{{"ALL PRIVILEGES", "ON *.*"}, {"SELECT", "ON *.*"}, {"ALL PRIVILEGES", onCatalog}, {"SELECT", onCatalog}};

View on GitHub (pinned to e952770a21)

Solutions

  1. Raise max_allowed_packet in the proxy's server configuration (and on backend MySQL) to exceed the largest parameter sent via mysql_send_long_data.
  2. Split the payload: send long data for a parameter in smaller statements, or stream the BLOB through a side channel and reference it (e.g. LOAD_FILE / staging table).
  3. If you do not need binary-protocol long data, switch the driver path to standard COM_QUERY execution with the full parameter inline (within max_allowed_packet).
  4. Verify the setting took effect on the proxy side (the check uses the proxy's configured value, not the backend's).

Example fix

# before (server.yaml / rule)
maxAllowedPacket: 4194304  # 4MB, BLOB is 32MB

# after
maxAllowedPacket: 67108864  # 64MB, covers the largest long-data parameter
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: check payload size before sending long data
long maxPacket = fetchMaxAllowedPacketFromProxy(); // e.g. SELECT @@max_allowed_packet via proxy
if (blobBytes.length > maxPacket) {
    throw new IllegalArgumentException("Parameter of " + blobBytes.length + " bytes exceeds max_allowed_packet=" + maxPacket);
}
stmt.sendLongData(paramIndex, blobBytes);

Try / catch

// SQLException with SQLState 'HY000' and vendor code 1105 at execute time (deferred)
try {
    stmt.execute();
} catch (SQLException e) {
    if (e.getErrorCode() == 1105 && e.getMessage().contains("max_allowed_packet")) {
        throw new IllegalStateException("Long-data parameter too large; raise max_allowed_packet on the proxy or chunk the upload", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling mysql_send_long_data() (COM_STMT_SEND_LONG_DATA) with a cumulative byte count for one parameter that exceeds max_allowed_packet, then executing or describing the statement — getLongDataIndexes() throws because longDataTooLarge is true.

Common situations: Uploading large BLOBs/CLOBs through the binary protocol via send_long_data (common with MySQL Connector/C and some C/ODBC paths) while the proxy's max_allowed_packet is at its default; increasing max_allowed_packet on the backend server but not on the proxy rule; chunked long-data sends that individually pass but cumulatively exceed the limit.

Related errors


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