apache/pulsar · error · IllegalArgumentException
Windows Function not support delivery semantics.
Error message
Windows Function not support delivery semantics.
What it means
Pulsar Functions windowing only supports certain delivery semantics. When a WindowConfig is present, convert() rejects EFFECTIVELY_ONCE and MANUAL processing guarantees with this IllegalArgumentException ('Windows Function not support <X> delivery semantics'), because the windowing implementation cannot provide them.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:323
RetryDetails retryDetails = functionDetails.setRetryDetails();
retryDetails.setMaxMessageRetries(functionConfig.getMaxMessageRetries());
if (isNotEmpty(functionConfig.getDeadLetterTopic())) {
retryDetails.setDeadLetterTopic(functionConfig.getDeadLetterTopic());
}
}
Map<String, Object> configs = new HashMap<>();
if (functionConfig.getUserConfig() != null) {
configs.putAll(functionConfig.getUserConfig());
}
// windowing related
WindowConfig windowConfig = functionConfig.getWindowConfig();
if (windowConfig != null) {
// Windows Function not support MANUAL and EFFECTIVELY_ONCE.
if (functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE
|| functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.MANUAL) {
throw new IllegalArgumentException(
"Windows Function not support "
+ functionConfig.getProcessingGuarantees() + " delivery semantics.");
} else {
// Override functionConfig.getProcessingGuarantees to MANUAL, and set windowsFunction is guarantees
windowConfig.setProcessingGuarantees(WindowConfig.ProcessingGuarantees
.valueOf(functionDetails.getProcessingGuarantees().name()));
functionDetails.setProcessingGuarantees(ProcessingGuarantees.MANUAL);
}
windowConfig.setActualWindowFunctionClassName(extractedDetails.getFunctionClassName());
configs.put(WindowConfig.WINDOW_CONFIG_KEY, windowConfig);
// set class name to window function executor
functionDetails.setClassName("org.apache.pulsar.functions.windowing.WindowFunctionExecutor");
} else {
if (extractedDetails.getFunctionClassName() != null) {
functionDetails.setClassName(extractedDetails.getFunctionClassName());
}
}
if (!configs.isEmpty()) {View on GitHub (pinned to 820761864e)
Solutions
- Remove the windowConfig if you require EFFECTIVELY_ONCE processing guarantees
- Set processingGuarantees to ATLEAST_ONCE or ATMOST_ONCE for windowed functions
- If MANUAL was set implicitly, explicitly set a supported guarantee before submitting the windowed function
- Use non-windowed function logic plus external deduplication if exactly-once semantics are mandatory
Example fix
// before cfg.setWindowConfig(new WindowConfig()); cfg.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE); // throws // after cfg.setWindowConfig(new WindowConfig()); cfg.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE); // supported for windowing
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate windowing + guarantee combination
if (cfg.getWindowConfig() != null
&& (cfg.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE
|| cfg.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.MANUAL)) {
throw new IllegalArgumentException("Windowed functions require ATLEAST_ONCE or ATMOST_ONCE");
} Try / catch
try {
FunctionDetails d = FunctionConfigUtils.convert(cfg, pkg);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Windows Function not support")) {
cfg.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
d = FunctionConfigUtils.convert(cfg, pkg); // retry with supported guarantee
} else {
throw e;
}
} Prevention
- Remember windowing only supports ATLEAST_ONCE and ATMOST_ONCE
- Never blanket-apply EFFECTIVELY_ONCE across all function configs in migration scripts
- Validate windowed function configs before CLI submission
- Document the guarantee limitation for users of your function platform
When it happens
Trigger: Submitting a function whose FunctionConfig has both a non-null windowConfig and processingGuarantees set to EFFECTIVELY_ONCE (or MANUAL) — e.g. a windowed function created with --processing-guarantees EFFECTIVELY_ONCE via the CLI or REST API.
Common situations: Developers adding at-least-once/effectively-once guarantees to an existing windowed function assuming all guarantees are supported; copy-pasted function configs combining windowing with effectively-once; migration scripts setting guarantees globally for all functions including windowed ones.
Related errors
- 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
- Window length must be positive [${windowLengthCount}]
- Window length must be positive [${windowLengthDurationMs}]
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ddb28a2a5ce20b85.
Report an issue: GitHub.