apache/seatunnel · warning

String range split is unsafe for table

Error message

String range split is unsafe for table {}, split column {}. Requested strategy: {}, fallback strategy: {}, reason: {}

What it means

ChunkSplitter.resolveStringSplitStrategy() evaluates whether the requested string-split strategy (RANGE) is safe for the table/column based on safety checks (decision). When unsafe it logs this WARN and degrades to a fallback strategy (HASH if the dialect supports it, otherwise NONE = parallelism 1).

Solutions

  1. Accept the HASH fallback (correct, just different partitioning)
  2. Choose a safe numeric or timestamp split column instead
  3. Set split.string-split-strategy to HASH explicitly to silence the warning
  4. Normalize the column's collation/charset to one with stable ordering

Example fix

// before
split.string-split-strategy = "RANGE"
// after
split.string-split-strategy = "HASH"
Defensive patterns

Strategy: fallback

Validate before calling

// inspect collation before choosing RANGE
if (!columnCollationIsBinarySafe(table, splitKey)) {
    config.set("split.string-split-strategy", "HASH");
}

Prevention

When it happens

Trigger: split.string-split-strategy = RANGE (or AUTO resolving to RANGE) but safety checks for the split key fail — e.g. column collation makes range comparisons unsafe, unsupported charset, or dialect-specific hazards.

Common situations: Tables with case-insensitive or binary collations that break lexicographic ordering; non-UTF8 charsets; columns with mixed-case keys where range splits would mis-partition rows.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/bc5d1648bf2cce01. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/ChunkSplitter.java:225

        StringRangeSplitDecision decision =
                jdbcDialect.validateStringRangeSplit(
                        getOrEstablishConnection(), table, splitKeyName, 256);
        if (decision.isSafe()) {
            return StringSplitStrategy.RANGE;
        }
        if (requestedStrategy == StringSplitStrategy.RANGE) {
            throw new JdbcConnectorException(
                    CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
                    String.format(
                            "String range split is unsafe for table %s, split column %s: %s",
                            table.getTablePath(), splitKeyName, decision.getReason()));
        }

        StringSplitStrategy fallback =
                jdbcDialect.supportHashSplitter()
                        ? StringSplitStrategy.HASH
                        : StringSplitStrategy.NONE;
        log.warn(
                "String range split is unsafe for table {}, split column {}. Requested strategy: {}, fallback strategy: {}, reason: {}",
                table.getTablePath(),
                splitKeyName,
                requestedStrategy,
                fallback,
                decision.getReason());
        return fallback;
    }

    protected PreparedStatement createSingleSplitStatement(JdbcSourceSplit split)
            throws SQLException {
        String splitQuery = split.getSplitQuery();
        if (StringUtils.isEmpty(splitQuery)) {
            splitQuery =
                    String.format(
                            "SELECT * FROM %s", jdbcDialect.tableIdentifier(split.getTablePath()));
        }
        splitQuery = applyUserWhereCondition(splitQuery);

View on GitHub (pinned to cf67b549a7)