apache/pulsar · error · IllegalArgumentException
Watermark interval must be positive [${watermarkEmitInterval
Error message
Watermark interval must be positive [${watermarkEmitIntervalMs}] What it means
WindowConfigUtils.validate(), inside the timestamp-extractor branch, requires watermarkEmitIntervalMs — how often watermarks are emitted downstream — to be a positive duration when provided. This IllegalArgumentException is thrown when the value is zero or negative, since a non-positive emit interval would make watermark generation degenerate.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/WindowConfigUtils.java:75
}
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) {
windowConfig.setSlidingIntervalCount(windowConfig.getWindowLengthCount());
}
if (windowConfig.getTimestampExtractorClassName() != null) {
if (windowConfig.getMaxLagMs() == null) {
windowConfig.setMaxLagMs(DEFAULT_MAX_LAG_MS);View on GitHub (pinned to 820761864e)
Solutions
- Set watermarkEmitIntervalMs to a positive value in milliseconds (e.g. 1000).
- Set the field to null to use the engine default emit interval.
- Validate the config with WindowConfigUtils.validate() before submission.
Example fix
// before WindowConfig.builder().setTimestampExtractorClassName(MyExtractor.class.getName()).setWatermarkEmitIntervalMs(0).build(); // after WindowConfig.builder().setTimestampExtractorClassName(MyExtractor.class.getName()).setWatermarkEmitIntervalMs(1000).build();
Defensive patterns
Strategy: validation
Validate before calling
if (cfg.getTimestampExtractorClassName() != null && cfg.getWatermarkEmitIntervalMs() != null && cfg.getWatermarkEmitIntervalMs() <= 0) {
throw new IllegalArgumentException("watermarkEmitIntervalMs must be > 0, got " + cfg.getWatermarkEmitIntervalMs());
} Try / catch
try {
WindowConfigUtils.validate(windowConfig);
} catch (IllegalArgumentException e) {
// reject submission with the validation message
throw e;
} Prevention
- Omit the field (null) to use defaults instead of setting 0.
- Compute intervals from Duration objects to avoid truncation to 0.
- Add a unit test validating every WindowConfig template used in deployment.
When it happens
Trigger: Calling WindowConfigUtils.validate(windowConfig) with a WindowConfig that has timestampExtractorClassName set and watermarkEmitIntervalMs <= 0 (e.g. 0L).
Common situations: Leaving a 0 placeholder in a generated/twelved config; unit-conversion bugs (seconds truncated to 0 ms); disabling watermark emission by setting 0 instead of removing the field.
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
- Lag duration must be positive [${maxLagMs}]
- Windows Function not support delivery semantics.
- Cannot enable auto ack when using windowing functionality
- Window length is not specified
- Window length for time and count are set! Please set one or
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/555ae205a4f3a467.
Report an issue: GitHub.