{"record":{"id":"26ebca7e24b21d2a","repo":"apache/pulsar","slug":"autoack-cannot-be-altered-26ebca","errorCode":null,"errorMessage":"AutoAck cannot be altered","messagePattern":"AutoAck cannot be altered","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java","lineNumber":708,"sourceCode":"        if (newConfig.getSecrets() != null) {\n            mergedConfig.setSecrets(newConfig.getSecrets());\n        }\n        if (newConfig.getParallelism() != null) {\n            mergedConfig.setParallelism(newConfig.getParallelism());\n        }\n        if (newConfig.getRetainOrdering() != null && !newConfig.getRetainOrdering()\n                .equals(existingConfig.getRetainOrdering())) {\n            throw new IllegalArgumentException(\"Retain Ordering cannot be altered\");\n        }\n        if (newConfig.getRetainKeyOrdering() != null && !newConfig.getRetainKeyOrdering()\n                .equals(existingConfig.getRetainKeyOrdering())) {\n            throw new IllegalArgumentException(\"Retain Key Ordering cannot be altered\");\n        }\n        @SuppressWarnings(\"deprecation\")\n        boolean autoAckChanged = newConfig.getAutoAck() != null\n                && !newConfig.getAutoAck().equals(existingConfig.getAutoAck());\n        if (autoAckChanged) {\n            throw new IllegalArgumentException(\"AutoAck cannot be altered\");\n        }\n        if (newConfig.getResources() != null) {\n            mergedConfig\n                    .setResources(ResourceConfigUtils.merge(existingConfig.getResources(), newConfig.getResources()));\n        }\n        if (newConfig.getTimeoutMs() != null) {\n            mergedConfig.setTimeoutMs(newConfig.getTimeoutMs());\n        }\n        if (newConfig.getCleanupSubscription() != null) {\n            mergedConfig.setCleanupSubscription(newConfig.getCleanupSubscription());\n        }\n        if (!StringUtils.isEmpty(newConfig.getArchive())) {\n            mergedConfig.setArchive(newConfig.getArchive());\n        }\n        if (!StringUtils.isEmpty(newConfig.getRuntimeFlags())) {\n            mergedConfig.setRuntimeFlags(newConfig.getRuntimeFlags());\n        }\n        if (!StringUtils.isEmpty(newConfig.getCustomRuntimeOptions())) {","sourceCodeStart":690,"sourceCodeEnd":726,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java#L690-L726","documentation":"Thrown by SinkConfigUtils.validateUpdate when the deprecated autoAck field is set in the new config and differs from the existing value. autoAck is deprecated and immutable to prevent changing acknowledgment semantics on a running sink.","triggerScenarios":"Updating a sink whose config carries an autoAck value different from the deployed one; older configs serialized with autoAck: true/false are used against a sink created with the opposite value.","commonSituations":"Legacy configs from old Pulsar versions still containing autoAck; tool-generated configs that emit the deprecated field with a default differing from the deployed sink.","solutions":["Remove the autoAck field from the update config entirely (it is deprecated)","If present, set it to the same value as the existing sink","Migrate config files to stop emitting autoAck"],"exampleFix":"// before\nsinkConfig.setAutoAck(false); // deprecated, deployed sink has true\nadmin.sinks().updateSink(tenant, namespace, sinkConfig, null);\n// after\n// (do not set autoAck at all)\nadmin.sinks().updateSink(tenant, namespace, sinkConfig, null);","handlingStrategy":"validation","validationCode":"if (newCfg.getAutoAck() != null\n    && !newCfg.getAutoAck().equals(existing.getAutoAck())) {\n    throw new IllegalArgumentException(\"autoAck is deprecated and immutable; remove it from the config\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.sinks().updateSink(tenant, namespace, cfg, null);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"AutoAck cannot be altered\")) { /* strip autoAck field and retry */ }\n    else throw e;\n}","preventionTips":["Strip the deprecated autoAck field from all sink configs","Audit legacy YAMLs generated before the field was deprecated","Never serialize autoAck in tool-generated update payloads"],"tags":["pulsar","functions","deprecated-field","config-validation"],"backgroundTag":"immutable-config-field-update","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"}