apache/pulsar · error · IllegalArgumentException
AutoAck cannot be altered
Error message
AutoAck cannot be altered
What it means
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.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java:708
if (newConfig.getSecrets() != null) {
mergedConfig.setSecrets(newConfig.getSecrets());
}
if (newConfig.getParallelism() != null) {
mergedConfig.setParallelism(newConfig.getParallelism());
}
if (newConfig.getRetainOrdering() != null && !newConfig.getRetainOrdering()
.equals(existingConfig.getRetainOrdering())) {
throw new IllegalArgumentException("Retain Ordering cannot be altered");
}
if (newConfig.getRetainKeyOrdering() != null && !newConfig.getRetainKeyOrdering()
.equals(existingConfig.getRetainKeyOrdering())) {
throw new IllegalArgumentException("Retain Key Ordering cannot be altered");
}
@SuppressWarnings("deprecation")
boolean autoAckChanged = newConfig.getAutoAck() != null
&& !newConfig.getAutoAck().equals(existingConfig.getAutoAck());
if (autoAckChanged) {
throw new IllegalArgumentException("AutoAck cannot be altered");
}
if (newConfig.getResources() != null) {
mergedConfig
.setResources(ResourceConfigUtils.merge(existingConfig.getResources(), newConfig.getResources()));
}
if (newConfig.getTimeoutMs() != null) {
mergedConfig.setTimeoutMs(newConfig.getTimeoutMs());
}
if (newConfig.getCleanupSubscription() != null) {
mergedConfig.setCleanupSubscription(newConfig.getCleanupSubscription());
}
if (!StringUtils.isEmpty(newConfig.getArchive())) {
mergedConfig.setArchive(newConfig.getArchive());
}
if (!StringUtils.isEmpty(newConfig.getRuntimeFlags())) {
mergedConfig.setRuntimeFlags(newConfig.getRuntimeFlags());
}
if (!StringUtils.isEmpty(newConfig.getCustomRuntimeOptions())) {View on GitHub (pinned to 820761864e)
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
Example fix
// before sinkConfig.setAutoAck(false); // deprecated, deployed sink has true admin.sinks().updateSink(tenant, namespace, sinkConfig, null); // after // (do not set autoAck at all) admin.sinks().updateSink(tenant, namespace, sinkConfig, null);
Defensive patterns
Strategy: validation
Validate before calling
if (newCfg.getAutoAck() != null
&& !newCfg.getAutoAck().equals(existing.getAutoAck())) {
throw new IllegalArgumentException("autoAck is deprecated and immutable; remove it from the config");
} Try / catch
try {
admin.sinks().updateSink(tenant, namespace, cfg, null);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("AutoAck cannot be altered")) { /* strip autoAck field and retry */ }
else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Sink Names differ
- Subscription Name cannot be altered
- Input Topics cannot be altered
- isRegexPattern for input topic cannot be altered
- Processing Guarantees cannot be altered
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/26ebca7e24b21d2a.
Report an issue: GitHub.