apache/seatunnel · error · IllegalArgumentException

'${SourceOptions.STARTUP_MODE_KEY}' requires '${SourceOption

Error message

'${SourceOptions.STARTUP_MODE_KEY}' requires '${SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key()}' with '${SourceOptions.STARTUP_SPECIFIC_OFFSET_POS.key()}' when the mode is 'specific'.

What it means

When startup.mode=specific, an explicit binlog offset is mandatory. If neither specific-offset.file nor specific-offset.pos is configured, MySqlIncrementalSource cannot construct the required offset and throws this 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:117

     * GTID and skip fields are optional metadata on that same offset, not an alternative anchor.
     */
    private static Map<String, String> createSpecificStartupOffset(ReadonlyConfig config) {
        Optional<String> gtidSet = getValidatedGtidSet(config);
        boolean hasFile =
                config.getOptional(SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE).isPresent();
        boolean hasPos = config.getOptional(SourceOptions.STARTUP_SPECIFIC_OFFSET_POS).isPresent();

        if (hasFile != hasPos) {
            throw new IllegalArgumentException(
                    String.format(
                            "'%s' and '%s' must be configured together when '%s' is 'specific'.",
                            SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key(),
                            SourceOptions.STARTUP_SPECIFIC_OFFSET_POS.key(),
                            SourceOptions.STARTUP_MODE_KEY));
        }

        if (!hasFile) {
            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(

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add startup.specific-offset.file and startup.specific-offset.pos to the config when using startup.mode='specific'
  2. Switch startup.mode to 'initial' (snapshot) or 'latest' (tail binlog) if a specific offset isn't required
  3. Get a valid filename/position from SHOW BINARY LOG STATUS (or SHOW MASTER STATUS on older MySQL) on the source server

Example fix

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

Strategy: validation

Validate before calling

if (config.getString("startup.mode").equals("specific") && !config.hasPath("startup.specific-offset.file")) {
    throw new IllegalArgumentException("mode 'specific' requires startup.specific-offset.file and .pos");
}

Try / catch

try { createSource(config); } catch (IllegalArgumentException e) { LOG.error("startup.mode=specific needs specific-offset.file+pos: {}", e.getMessage()); System.exit(2); }

Prevention

When it happens

Trigger: createSpecificStartupOffset (via createStartupConfig) invoked with startup.mode='specific' but startup.specific-offset.file absent entirely (hasFile=false).

Common situations: User sets startup.mode='specific' but forgets to add the offset keys; mode renamed/changed from a different startup mode without removing/adding the matching options; copied config where offset block was commented out.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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