apache/seatunnel · warning

set checkpoint.mode failed, unknown checkpoint.mode

Error message

set checkpoint.mode failed, unknown checkpoint.mode [{}],only support exactly-once,at-least-once

What it means

This warning is emitted by AbstractFlinkRuntimeEnvironment.setCheckpoint when the user-provided 'checkpoint.mode' value in the SeaTunnel env block does not match one of the supported Flink checkpointing modes ('exactly-once' or 'at-least-once'). Instead of failing the job, the starter logs a warning and leaves the checkpointing mode unset, so Flink defaults apply. It signals a config typo rather than a runtime failure.

Solutions

  1. Fix checkpoint.mode in the env block of the SeaTunnel config to exactly 'exactly-once' or 'at-least-once' (lowercase, hyphenated).
  2. Remove the checkpoint.mode key entirely to accept the Flink default.
  3. Check the starter logs for this warning after job submission to confirm the mode took effect.

Example fix

// before
env {
  checkpoint.mode = EXACTLY_ONCE
}
// after
env {
  checkpoint.mode = "exactly-once"
}
Defensive patterns

Strategy: validation

Validate before calling

String mode = config.getString("checkpoint.mode");
if (!java.util.Arrays.asList("exactly-once","at-least-once").contains(mode)) {
    throw new IllegalArgumentException("checkpoint.mode must be exactly-once or at-least-once, got: " + mode);
}

Prevention

When it happens

Trigger: A job config's env block contains 'checkpoint.mode' with any value other than 'exactly-once' or 'at-least-once' (case-sensitive), e.g. 'exactly_once', 'EXACTLY-ONCE', 'once', or a misspelling; the value is passed through createStreamEnvironment -> setCheckpoint.

Common situations: Copying example configs that use underscores instead of hyphens; uppercase values after hand-editing; migrating configs from engines with different mode names (e.g. Flink SQL 'EXACTLY_ONCE' constants).

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-core/seatunnel-flink-starter/seatunnel-flink-starter-common/src/main/java/org/apache/seatunnel/core/starter/flink/execution/AbstractFlinkRuntimeEnvironment.java:129

        } else if (EnvironmentUtil.hasPathAndWaring(config, ConfigKeyName.CHECKPOINT_TIMEOUT)) {
            long timeout = config.getLong(ConfigKeyName.CHECKPOINT_TIMEOUT);
            checkpointConfig.setCheckpointTimeout(timeout);
        } else if (config.hasPath(EnvCommonOptions.CHECKPOINT_MIN_PAUSE.key())) {
            long minPause = config.getLong(EnvCommonOptions.CHECKPOINT_MIN_PAUSE.key());
            checkpointConfig.setMinPauseBetweenCheckpoints(minPause);
        }

        if (EnvironmentUtil.hasPathAndWaring(config, ConfigKeyName.CHECKPOINT_MODE)) {
            String mode = config.getString(ConfigKeyName.CHECKPOINT_MODE);
            switch (mode.toLowerCase()) {
                case "exactly-once":
                    checkpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
                    break;
                case "at-least-once":
                    checkpointConfig.setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE);
                    break;
                default:
                    LOGGER.warn(
                            "set checkpoint.mode failed, unknown checkpoint.mode [{}],only support exactly-once,at-least-once",
                            mode);
                    break;
            }
        }

        if (EnvironmentUtil.hasPathAndWaring(config, ConfigKeyName.CHECKPOINT_DATA_URI)) {
            String uri = config.getString(ConfigKeyName.CHECKPOINT_DATA_URI);
            StateBackend fsStateBackend = new FsStateBackend(uri);
            if (EnvironmentUtil.hasPathAndWaring(config, ConfigKeyName.STATE_BACKEND)) {
                String stateBackend = config.getString(ConfigKeyName.STATE_BACKEND);
                if ("rocksdb".equalsIgnoreCase(stateBackend)) {
                    StateBackend rocksDBStateBackend =
                            new RocksDBStateBackend(fsStateBackend, TernaryBoolean.TRUE);
                    environment.setStateBackend(rocksDBStateBackend);
                }
            } else {
                environment.setStateBackend(fsStateBackend);

View on GitHub (pinned to cf67b549a7)