apache/shardingsphere · error · InvalidParameterValueException

1231

1231

Error message

Variable '%s' can't be set to the value of '%s'

What it means

InvalidParameterValueException (error code 1231, MySQL 'Variable can't be set to value' semantics) thrown by MySQLSetVariableAdminExecutor.validateClientCharacterSet when the value assigned to character_set_client (directly or via SET NAMES) is in IMPERMISSIBLE_CLIENT_CHARACTER_SETS. MySQL rejects certain charsets as client charsets (historically ucs2, utf16, utf16le, utf32) because the wire protocol cannot frame them; the proxy mirrors this restriction.

Source

Thrown at proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutor.java:216

                }
                if (setNamesWithCollationAssignment) {
                    validateClientCharacterSet(context.getClientCharacterSetName());
                }
                return context.withConnectionCollation(collation);
            default:
                return context;
        }
    }
    
    private MySQLCharacterSets parseClientCharacterSet(final String value) {
        String normalizedValue = formatVariableValue(value).toLowerCase(Locale.ROOT);
        validateClientCharacterSet(normalizedValue);
        return parseCharacterSet(value);
    }
    
    private void validateClientCharacterSet(final String characterSet) {
        if (IMPERMISSIBLE_CLIENT_CHARACTER_SETS.contains(characterSet)) {
            throw new InvalidParameterValueException(CHARACTER_SET_CLIENT, characterSet);
        }
    }
    
    private MySQLSessionCharsetContext updateResultCharacterSet(final MySQLSessionCharsetContext context, final String value) {
        String normalizedValue = formatVariableValue(value).toLowerCase(Locale.ROOT);
        if (isKeyword(value, "null")) {
            return context.withoutResultConversion();
        }
        return "binary".equals(normalizedValue) ? context.withBinaryResult() : context.withResultCharacterSet(parseCharacterSet(value));
    }
    
    private MySQLCharacterSets parseCharacterSet(final String value) {
        String normalizedValue = formatVariableValue(value);
        return isKeyword(value, "default") ? MySQLConstants.DEFAULT_CHARSET : MySQLCharacterSets.findByCharacterSetName(normalizedValue);
    }
    
    private MySQLCharacterSets parseConnectionCharacterSet(final String value) {
        if (isKeyword(value, "default")) {

View on GitHub (pinned to e952770a21)

Solutions

  1. Use a client-safe charset such as utf8mb4 for the connection/session variables
  2. Keep column-level utf16/ucs2 definitions in DDL only; never assign them to character_set_client or SET NAMES
  3. If a client library sends these SETs automatically, disable or reconfigure that behavior (e.g. connector charset probes)

Example fix

-- before
SET NAMES utf16;

-- after
SET NAMES utf8mb4;
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> IMPERMISSIBLE = Set.of("ucs2", "utf16", "utf16le", "utf32");
public void checkClientCharset(final String value) {
    String v = value.trim().toLowerCase(Locale.ROOT);
    if (IMPERMISSIBLE.contains(v)) { throw new IllegalArgumentException("Not allowed as client charset: " + v); }
}

Prevention

When it happens

Trigger: SET character_set_client = utf16 / ucs2 / utf32 / utf16le, or SET NAMES utf16 (which routes through parseClientCharacterSet -> validateClientCharacterSet); the lowercased normalized value is found in the impermissible set and the exception is thrown with (CHARACTER_SET_CLIENT, value).

Common situations: Configs written for storage-side column charsets reused as connection charsets; tools or ORMs probing available charsets by SETting each one; legacy configs using utf16 for 'more unicode' on the connection.

Related errors


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