apache/seatunnel · error · IllegalArgumentException

must be >= 0

Error message

${STATE_CLEANUP_DELAY_MILLIS} must be >= 0

What it means

EngineConfig.setStateCleanupDelayMillis validates that stateCleanupDelayMillis is non-negative before storing it; a negative value in the engine YAML or a direct setter call throws IllegalArgumentException naming the STATE_CLEANUP_DELAY_MILLIS option.

Solutions

  1. Set the delay to a non-negative value (e.g. 60000) in the engine config.
  2. Remove the key to use the built-in default.
  3. To effectively disable cleanup, use a very large positive value instead of a negative one.

Example fix

# before
state-cleanup:
  delay-millis: -1
# after
state-cleanup:
  delay-millis: 60000
Defensive patterns

Strategy: validation

Validate before calling

long v = Long.parseLong(props.getProperty("state-cleanup.delay-millis", "0"));
if (v < 0) throw new IllegalArgumentException("state-cleanup.delay-millis must be >= 0, got " + v);

Try / catch

try {
    engineConfig.setStateCleanupDelayMillis(v);
} catch (IllegalArgumentException e) {
    throw new ConfigValidationException("invalid state-cleanup delay: " + v, e);
}

Prevention

When it happens

Trigger: Master's seatunnel.yaml sets the state-cleanup delay key to a negative number, or parseEngineConfig / a test calls setStateCleanupDelayMillis with a negative long.

Common situations: -1 intended as 'disabled'; negative value emitted by a config generator; unit confusion when hand-editing durations.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/EngineConfig.java:196

        this.reportNonTerminalJobState = reportNonTerminalJobState;
    }

    public void setTaskExecutionThreadShareMode(ThreadShareMode taskExecutionThreadShareMode) {
        checkNotNull(queueType);
        this.taskExecutionThreadShareMode = taskExecutionThreadShareMode;
    }

    public void setHistoryJobExpireMinutes(int historyJobExpireMinutes) {
        checkPositive(
                historyJobExpireMinutes,
                ServerConfigOptions.MasterServerConfigOptions.HISTORY_JOB_EXPIRE_MINUTES
                        + " must be > 0");
        this.historyJobExpireMinutes = historyJobExpireMinutes;
    }

    public void setStateCleanupDelayMillis(long stateCleanupDelayMillis) {
        if (stateCleanupDelayMillis < 0) {
            throw new IllegalArgumentException(
                    ServerConfigOptions.MasterServerConfigOptions.STATE_CLEANUP_DELAY_MILLIS
                            + " must be >= 0");
        }
        this.stateCleanupDelayMillis = stateCleanupDelayMillis;
    }

    public EngineConfig setQueueType(QueueType queueType) {
        checkNotNull(queueType);
        this.queueType = queueType;
        return this;
    }

    public enum ClusterRole {
        MASTER_AND_WORKER,
        MASTER,
        WORKER
    }

View on GitHub (pinned to cf67b549a7)