{"record":{"id":"7f19011188c30467","repo":"apache/pulsar","slug":"cannot-enable-auto-ack-when-using-windowing-functi","errorCode":null,"errorMessage":"Cannot enable auto ack when using windowing functionality","messagePattern":"Cannot enable auto ack when using windowing functionality","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java","lineNumber":850,"sourceCode":"                throw new IllegalArgumentException(\n                        String.format(\"DeadLetter topic %s is invalid\", functionConfig.getDeadLetterTopic()));\n            }\n        }\n\n        if (functionConfig.getParallelism() != null && functionConfig.getParallelism() <= 0) {\n            throw new IllegalArgumentException(\"Function parallelism must be a positive number\");\n        }\n        // Ensure that topics aren't being used as both input and output\n        verifyNoTopicClash(allInputTopics, functionConfig.getOutput());\n\n        WindowConfig windowConfig = functionConfig.getWindowConfig();\n        if (windowConfig != null) {\n            // set auto ack to false since windowing framework is responsible\n            // for acking and not the function framework\n            @SuppressWarnings(\"deprecation\")\n            Boolean windowAutoAck = functionConfig.getAutoAck();\n            if (windowAutoAck != null && windowAutoAck) {\n                throw new IllegalArgumentException(\"Cannot enable auto ack when using windowing functionality\");\n            }\n            WindowConfigUtils.validate(windowConfig);\n        }\n\n        if (functionConfig.getResources() != null) {\n            ResourceConfigUtils.validate(functionConfig.getResources());\n        }\n\n        if (functionConfig.getTimeoutMs() != null && functionConfig.getTimeoutMs() <= 0) {\n            throw new IllegalArgumentException(\"Function timeout must be a positive number\");\n        }\n\n        if (functionConfig.getTimeoutMs() != null\n                && functionConfig.getProcessingGuarantees() != null\n                && functionConfig.getProcessingGuarantees() != FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE) {\n            throw new IllegalArgumentException(\"Message timeout can only be specified with processing guarantee is \"\n                    + FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE.name());\n        }","sourceCodeStart":832,"sourceCodeEnd":868,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java#L832-L868","documentation":"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.","triggerScenarios":"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.","commonSituations":"Migrating legacy function manifests from older Pulsar versions where autoAck was commonly enabled, generating windowed function configs from templates that include autoAck: true.","solutions":["Remove the autoAck setting (or set it to false) when WindowConfig is present — windowing acks internally","Drop window config if windowing was not intended and autoAck is required","Update legacy CLI invocations to omit --auto-ack for windowed functions"],"exampleFix":"// before\nconfig.setWindowConfig(windowConfig);\nconfig.setAutoAck(true);\n// after\nconfig.setWindowConfig(windowConfig);\n// autoAck removed: windowing framework handles acking","handlingStrategy":"validation","validationCode":"if (config.getWindowConfig() != null\n        && Boolean.TRUE.equals(config.getAutoAck())) {\n    throw new IllegalArgumentException(\"autoAck must not be enabled with windowing\");\n}","typeGuard":"boolean windowingAckCompatible(FunctionConfig c) {\n    return c.getWindowConfig() == null || !Boolean.TRUE.equals(c.getAutoAck());\n}","tryCatchPattern":"try {\n    admin.functions().createFunction(functionConfig, sourceConfigLocation);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"auto ack\")) {\n        config.setAutoAck(false);\n        // resubmit\n    } else { throw e; }\n}","preventionTips":["Never set autoAck in windowed function templates","Migrate legacy configs to drop the deprecated autoAck field","Run FunctionConfigUtils.validate locally in tests before remote submission","Document windowing + autoAck incompatibility in your platform's function templates"],"tags":["pulsar-functions","windowing","ack","configuration"],"backgroundTag":"incompatible-function-options","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}