apache/seatunnel · error · IllegalArgumentException

'${SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key()}' and '$

Error message

'${SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE.key()}' and '${SourceOptions.STARTUP_SPECIFIC_OFFSET_POS.key()}' must be configured together when '${SourceOptions.STARTUP_MODE_KEY}' is 'specific'.

What it means

MySqlIncrementalSource validates that when startup.mode=specific, both startup.specific-offset.file and startup.specific-offset.pos are provided. If exactly one of them is set (hasFile != hasPos), the pair is inconsistent and the connector refuses to build a binlog offset, throwing this IllegalArgumentException at source creation time.

Source

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

        return new StartupConfig(
                startupMode,
                config.get(SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE),
                config.get(SourceOptions.STARTUP_SPECIFIC_OFFSET_POS),
                config.get(SourceOptions.STARTUP_TIMESTAMP));
    }

    /*
     * Debezium's MySqlOffsetContext.Loader requires file and pos for a specific startup offset.
     * 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(

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set both startup.specific-offset.file and startup.specific-offset.pos together in the source config
  2. If you don't need an exact offset, use startup.mode='initial' or 'latest' instead of 'specific'
  3. Verify keys are spelled correctly and nested under the same source block in the HOCON/YAML config

Example fix

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

Strategy: validation

Validate before calling

boolean hasFile = config.hasPath("startup.specific-offset.file");
boolean hasPos = config.hasPath("startup.specific-offset.pos");
if (hasFile != hasPos) {
    throw new IllegalArgumentException("startup.specific-offset.file and .pos must be set together");
}

Type guard

if (!(typeof file === "string" && file.length > 0) || !(typeof pos === "number" && pos > 0)) throw new Error("file and pos must both be set");

Try / catch

try { source = new MySqlIncrementalSource<>(options); } catch (IllegalArgumentException e) { LOG.error("Invalid specific startup offset pair: {}", e.getMessage()); throw new ConfigException(e); }

Prevention

When it happens

Trigger: Calling createSpecificStartupOffset via createStartupConfig with startup.mode='specific' where only startup.specific-offset.file OR only startup.specific-offset.pos is configured.

Common situations: User adds a binlog filename but forgets the position (or vice versa); config template copies only one key; YAML indentation drops the second key; user assumes file alone is sufficient like some other CDC tools.

Related errors


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