apache/pulsar · error · IllegalArgumentException

Lag duration must be positive [${maxLagMs}]

Error message

Lag duration must be positive [${maxLagMs}]

What it means

WindowConfigUtils.validate() checks watermark/lag settings when a timestampExtractorClassName is configured. maxLagMs bounds how late events may arrive relative to the watermark; this IllegalArgumentException is thrown when maxLagMs is provided and is negative. (Zero is allowed here — the check is `< 0`, unlike other interval checks.)

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/WindowConfigUtils.java:69

        if (windowConfig.getSlidingIntervalCount() != null) {
            if (windowConfig.getSlidingIntervalCount() <= 0) {
                throw new IllegalArgumentException(
                        "Sliding interval must be positive [" + windowConfig.getSlidingIntervalCount() + "]");
            }
        }

        if (windowConfig.getSlidingIntervalDurationMs() != null) {
            if (windowConfig.getSlidingIntervalDurationMs() <= 0) {
                throw new IllegalArgumentException(
                        "Sliding interval must be positive [" + windowConfig.getSlidingIntervalDurationMs() + "]");
            }
        }

        if (windowConfig.getTimestampExtractorClassName() != null) {
            if (windowConfig.getMaxLagMs() != null) {
                if (windowConfig.getMaxLagMs() < 0) {
                    throw new IllegalArgumentException(
                            "Lag duration must be positive [" + windowConfig.getMaxLagMs() + "]");
                }
            }
            if (windowConfig.getWatermarkEmitIntervalMs() != null) {
                if (windowConfig.getWatermarkEmitIntervalMs() <= 0) {
                    throw new IllegalArgumentException(
                            "Watermark interval must be positive [" + windowConfig.getWatermarkEmitIntervalMs() + "]");
                }
            }
        }
    }

    public static void inferMissingArguments(WindowConfig windowConfig) {
        if (windowConfig.getWindowLengthDurationMs() != null && windowConfig.getSlidingIntervalDurationMs() == null) {
            windowConfig.setSlidingIntervalDurationMs(windowConfig.getWindowLengthDurationMs());
        }

        if (windowConfig.getWindowLengthCount() != null && windowConfig.getSlidingIntervalCount() == null) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Set windowConfig.maxLagMs to a non-negative value (0 for no allowed lag, or a positive bound like 60000).
  2. Remove maxLagMs (set to null) to use the default if you did not intend to bound lateness.
  3. Guard the computed value: clamp with Math.max(0, computedLagMs) before building the config.

Example fix

// before
WindowConfig.builder().setTimestampExtractorClassName(MyExtractor.class.getName()).setMaxLagMs(-1).build();
// after
WindowConfig.builder().setTimestampExtractorClassName(MyExtractor.class.getName()).setMaxLagMs(60000).build();
Defensive patterns

Strategy: validation

Validate before calling

if (cfg.getTimestampExtractorClassName() != null && cfg.getMaxLagMs() != null && cfg.getMaxLagMs() < 0) {
    throw new IllegalArgumentException("maxLagMs must be >= 0, got " + cfg.getMaxLagMs());
}

Try / catch

try {
    WindowConfigUtils.validate(windowConfig);
} catch (IllegalArgumentException e) {
    throw new IllegalArgumentException("Fix maxLagMs: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling WindowConfigUtils.validate(windowConfig) on a WindowConfig that sets timestampExtractorClassName and has maxLagMs < 0 (e.g. -1L).

Common situations: Using -1 as a sentinel for 'unbounded' or 'unset' lag in handwritten configs; computing the lag as a difference (current - event time) that went negative due to clock skew; copying a config template where the lag placeholder was negative.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/5d02a3dd8f888148. Report an issue: GitHub.