apache/pulsar · error · IllegalArgumentException

Cannot enable auto ack when using windowing functionality

Error message

Cannot enable auto ack when using windowing functionality

What it means

Windowed functions manage their own acknowledgement semantics: the windowing framework acks messages, so the deprecated autoAck flag must not be true. doCommonChecks throws this IllegalArgumentException when a WindowConfig is present and getAutoAck() is TRUE, preventing conflicting ack behavior between the function framework and the windowing layer.

Solutions

  1. Remove the autoAck setting (or set it to false) when WindowConfig is present — windowing acks internally
  2. Drop window config if windowing was not intended and autoAck is required
  3. Update legacy CLI invocations to omit --auto-ack for windowed functions

Example fix

// before
config.setWindowConfig(windowConfig);
config.setAutoAck(true);
// after
config.setWindowConfig(windowConfig);
// autoAck removed: windowing framework handles acking
Defensive patterns

Strategy: validation

Validate before calling

if (config.getWindowConfig() != null
        && Boolean.TRUE.equals(config.getAutoAck())) {
    throw new IllegalArgumentException("autoAck must not be enabled with windowing");
}

Type guard

boolean windowingAckCompatible(FunctionConfig c) {
    return c.getWindowConfig() == null || !Boolean.TRUE.equals(c.getAutoAck());
}

Try / catch

try {
    admin.functions().createFunction(functionConfig, sourceConfigLocation);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("auto ack")) {
        config.setAutoAck(false);
        // resubmit
    } else { throw e; }
}

Prevention

When it happens

Trigger: createFunction/updateFunction with a non-null windowConfig (windowed function) and functionConfig.getAutoAck() == Boolean.TRUE, e.g. legacy configs that set --auto-ack true (the old CLI default) together with --window-length/--sliding-interval options.

Common situations: Migrating legacy function manifests from older Pulsar versions where autoAck was commonly enabled, generating windowed function configs from templates that include autoAck: true.

Related errors


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

Appendix: source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:850

                throw new IllegalArgumentException(
                        String.format("DeadLetter topic %s is invalid", functionConfig.getDeadLetterTopic()));
            }
        }

        if (functionConfig.getParallelism() != null && functionConfig.getParallelism() <= 0) {
            throw new IllegalArgumentException("Function parallelism must be a positive number");
        }
        // Ensure that topics aren't being used as both input and output
        verifyNoTopicClash(allInputTopics, functionConfig.getOutput());

        WindowConfig windowConfig = functionConfig.getWindowConfig();
        if (windowConfig != null) {
            // set auto ack to false since windowing framework is responsible
            // for acking and not the function framework
            @SuppressWarnings("deprecation")
            Boolean windowAutoAck = functionConfig.getAutoAck();
            if (windowAutoAck != null && windowAutoAck) {
                throw new IllegalArgumentException("Cannot enable auto ack when using windowing functionality");
            }
            WindowConfigUtils.validate(windowConfig);
        }

        if (functionConfig.getResources() != null) {
            ResourceConfigUtils.validate(functionConfig.getResources());
        }

        if (functionConfig.getTimeoutMs() != null && functionConfig.getTimeoutMs() <= 0) {
            throw new IllegalArgumentException("Function timeout must be a positive number");
        }

        if (functionConfig.getTimeoutMs() != null
                && functionConfig.getProcessingGuarantees() != null
                && functionConfig.getProcessingGuarantees() != FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE) {
            throw new IllegalArgumentException("Message timeout can only be specified with processing guarantee is "
                    + FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE.name());
        }

View on GitHub (pinned to 820761864e)