apache/seatunnel · error · IllegalArgumentException

'${SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key()}' must n

Error message

'${SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key()}' must not be blank.

What it means

The configured startup.specific-offset.file value is present but blank (empty or whitespace-only). A binlog filename is required to build the BinlogOffset, so createSpecificStartupOffset rejects it with an IllegalArgumentException.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mysql/source/MySqlIncrementalSource.java:135

            throw new IllegalArgumentException(
                    String.format(
                            "'%s' requires '%s' with '%s' when the mode is 'specific'.",
                            SourceOptions.STARTUP_MODE_KEY,
                            SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key(),
                            SourceOptions.STARTUP_SPECIFIC_OFFSET_POS.key()));
        }

        long skipEvents =
                getNonNegativeSkipValue(
                        config, MySqlIncrementalSourceOptions.STARTUP_SPECIFIC_OFFSET_SKIP_EVENTS);
        long skipRows =
                getNonNegativeSkipValue(
                        config, MySqlIncrementalSourceOptions.STARTUP_SPECIFIC_OFFSET_SKIP_ROWS);

        Map<String, String> offset = new LinkedHashMap<>();
        String file = config.get(SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE);
        if (StringUtils.isBlank(file)) {
            throw new IllegalArgumentException(
                    String.format(
                            "'%s' must not be blank.",
                            SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key()));
        }
        offset.put(BinlogOffset.BINLOG_FILENAME_OFFSET_KEY, file);
        offset.put(
                BinlogOffset.BINLOG_POSITION_OFFSET_KEY,
                String.valueOf(config.get(SourceOptions.STARTUP_SPECIFIC_OFFSET_POS)));
        if (gtidSet.isPresent()) {
            offset.put(BinlogOffset.GTID_SET_KEY, gtidSet.get());
        }
        offset.put(BinlogOffset.EVENTS_TO_SKIP_OFFSET_KEY, String.valueOf(skipEvents));
        offset.put(BinlogOffset.ROWS_TO_SKIP_OFFSET_KEY, String.valueOf(skipRows));
        return offset;
    }

    /* Validate the configured GTID set before adding it to Debezium's offset map. */
    private static Optional<String> getValidatedGtidSet(ReadonlyConfig config) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set startup.specific-offset.file to a real binlog filename, e.g. "mysql-bin.000003"
  2. Run SHOW BINARY LOG STATUS (or SHOW MASTER STATUS) on MySQL to obtain the current filename
  3. Remove the empty key and use startup.mode='latest' if no fixed offset is wanted

Example fix

// before
specific-offset.file = ""
specific-offset.pos = 4
// after
specific-offset.file = "mysql-bin.000003"
specific-offset.pos = 4
Defensive patterns

Strategy: validation

Validate before calling

String file = config.getString("startup.specific-offset.file");
if (file == null || file.trim().isEmpty()) {
    throw new IllegalArgumentException("startup.specific-offset.file must be a non-blank binlog filename");
}

Type guard

boolean validFile(String f) { return f != null && !f.trim().isEmpty(); }

Try / catch

try { createSource(config); } catch (IllegalArgumentException e) { LOG.error("Blank binlog file: {}", e.getMessage()); throw new ConfigException(e); }

Prevention

When it happens

Trigger: createSpecificStartupOffset with startup.mode='specific' where config.get(STARTUP_SPECIFIC_OFFSET_FILE) returns "" or " " (StringUtils.isBlank).

Common situations: Config placeholder like specific-offset.file = "" left unfilled; env variable substitution produced an empty string; user pasted only a position and an empty file value.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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