apache/seatunnel · error · SeaTunnelException

PostgreSQL-CDC startup.mode 'COMMITTED_OFFSET' requires an e

Error message

PostgreSQL-CDC startup.mode 'COMMITTED_OFFSET' requires an explicit 'slot.name' option.

What it means

PostgresIncrementalSource.validateStartupOptions enforces that startup.mode = COMMITTED_OFFSET is paired with a non-empty slot.name option, because resuming from a committed LSN requires reading from a known replication slot. Missing or blank slot.name fails with SeaTunnelException.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-postgres/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/postgres/source/PostgresIncrementalSource.java:170

    public Optional<String> driverName() {
        return Optional.of("org.postgresql.Driver");
    }

    @Override
    public List<SchemaChangeType> supports() {
        return Collections.singletonList(SchemaChangeType.ADD_COLUMN);
    }

    private void validateStartupOptions(ReadonlyConfig options, StartupConfig startupConfig) {
        if (startupConfig.getStartupMode() != StartupMode.COMMITTED_OFFSET) {
            return;
        }
        Optional<String> slotName =
                options.getOptional(PostgresIncrementalSourceOptions.SLOT_NAME)
                        .map(String::trim)
                        .filter(name -> !name.isEmpty());
        if (!slotName.isPresent()) {
            throw new SeaTunnelException(
                    String.format(
                            "PostgreSQL-CDC startup.mode '%s' requires an explicit '%s' option.",
                            StartupMode.COMMITTED_OFFSET,
                            PostgresIncrementalSourceOptions.SLOT_NAME.key()));
        }
    }

    private void validateSchemaEvolutionOptions(ReadonlyConfig options) {
        if (options.get(SourceOptions.SCHEMA_CHANGES_ENABLED)
                && !"pgoutput"
                        .equalsIgnoreCase(
                                options.get(
                                        PostgresIncrementalSourceOptions.DECODING_PLUGIN_NAME))) {
            throw new SeaTunnelException(
                    String.format(
                            "PostgreSQL-CDC schema evolution requires '%s = pgoutput' because PostgreSQL RELATION messages provide the changed schema.",
                            PostgresIncrementalSourceOptions.DECODING_PLUGIN_NAME.key()));
        }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add slot.name = "<existing-slot>" to the PostgreSQL-CDC source options.
  2. Ensure the named slot exists in Postgres (SELECT * FROM pg_replication_slots;).
  3. Or choose a different startup.mode (e.g. INITIAL or LATEST_OFFSET) that doesn't require an explicit slot.
  4. Check for whitespace-only values that pass existence checks but fail this validation.

Example fix

// before
startup.mode = "COMMITTED_OFFSET"
// after
startup.mode = "COMMITTED_OFFSET"
slot.name = "seatunnel_slot"
Defensive patterns

Strategy: validation

Validate before calling

if ("COMMITTED_OFFSET".equals(startupMode) && (slotName == null || slotName.trim().isEmpty())) {
  throw new IllegalArgumentException("COMMITTED_OFFSET requires a non-empty slot.name");
}

Prevention

When it happens

Trigger: Thrown from validateStartupOptions (via getStartupConfig) when startup.mode = 'COMMITTED_OFFSET' and the SLOT_NAME option is absent, empty, or whitespace-only.

Common situations: Users copying a sample config without slot.name; assuming the default slot applies; trimming/typo leaving an empty value.

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/24882a6d3f51a86d. Report an issue: GitHub.