apache/seatunnel · error · IllegalArgumentException

intervalMs must be positive, got: %s

Error message

intervalMs must be positive, got: %s

What it means

registerTimerFlushTask validates that the timer flush interval (intervalMs) is strictly positive before scheduling the periodic flush task. A non-positive interval would create a useless or hot-looping scheduled task, so the constructor-level guard rejects it immediately with IllegalArgumentException.

Source

Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/TaskExecutionService.java:1011

    }

    /**
     * Register or replace a periodic timer-flush task for one source subtask.
     *
     * <p>If a timer already exists for the same {@link TaskLocation}, cancel it first. The task is
     * scheduled with fixed delay on {@code timerFlushWorker} and stored in {@code
     * timerFlushFutures}.
     *
     * @param taskLocation source subtask location (map key)
     * @param callback flush callback to run on each tick
     * @param intervalMs flush interval in milliseconds, must be > 0
     * @return scheduled future for later cancellation
     * @throws IllegalArgumentException if intervalMs <= 0
     */
    public ScheduledFuture<?> registerTimerFlushTask(
            TaskLocation taskLocation, Runnable callback, long intervalMs) {
        if (intervalMs <= 0) {
            throw new IllegalArgumentException("intervalMs must be positive, got: " + intervalMs);
        }
        TaskGroupLocation groupLocation = taskLocation.getTaskGroupLocation();
        ConcurrentMap<TaskLocation, ScheduledFuture<?>> groupFutures =
                timerFlushFutures.computeIfAbsent(groupLocation, k -> new ConcurrentHashMap<>());

        ScheduledFuture<?> existing = groupFutures.remove(taskLocation);
        if (existing != null && !existing.isDone()) {
            existing.cancel(false);
        }

        MDCScheduledExecutorService mdcTimerFlushWorker = MDCTracer.tracing(timerFlushWorker);
        Runnable namedCallback = new NamedTaskWrapper(callback, "TimerFlush-" + taskLocation);
        ScheduledFuture<?> future =
                mdcTimerFlushWorker.scheduleWithFixedDelay(
                        namedCallback, intervalMs, intervalMs, TimeUnit.MILLISECONDS);
        groupFutures.put(taskLocation, future);
        logger.info(
                String.format(

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Pass a strictly positive intervalMs, e.g. at least 1 ms; use a distinct flag to disable flushing instead of 0
  2. Check the metrics/timer flush interval config option value and its default — fix the config or the default
  3. Validate/clamp the interval at config-parse time (e.g. require >= 1000ms) so the error surfaces early with the config key
  4. If converting units, verify the multiplier (e.g. seconds * 1000) so a 0 second value doesn't silently become 0 ms

Example fix

// before
long intervalMs = 0; // intended: disabled
taskExecutionService.registerTimerFlushTask(taskLocation, callback, intervalMs);

// after
long intervalMs = metricsFlushIntervalMs; // from config
if (intervalMs > 0) {
    taskExecutionService.registerTimerFlushTask(taskLocation, callback, intervalMs);
}
Defensive patterns

Strategy: validation

Validate before calling

if (intervalMs == null || intervalMs <= 0) {
    throw new IllegalArgumentException("intervalMs must be > 0, got: " + intervalMs);
}

Type guard

boolean isValidInterval(Long ms) { return ms != null && ms > 0; }

Prevention

When it happens

Trigger: Calling TaskExecutionService.registerTimerFlushTask(taskLocation, callback, intervalMs) with intervalMs <= 0 — typically from a metrics/timer flush configuration resolved to 0, a negative value, or an uninitialized long default.

Common situations: Metrics flush interval set to 0 in job config believing 0 means 'disabled'; a config option typed as long whose default was never set; unit conversion bugs (seconds vs milliseconds) producing 0.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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