apache/pulsar · error · IllegalArgumentException
Retain Key Ordering cannot be altered
Error message
Retain Key Ordering cannot be altered
What it means
Thrown by SinkConfigUtils.validateUpdate when retainKeyOrdering is set and differs from the existing sink's value. Like retainOrdering, key ordering is fixed at creation and cannot be changed through the update path.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java:702
.equals(existingConfig.getProcessingGuarantees())) {
throw new IllegalArgumentException("Processing Guarantees cannot be altered");
}
if (newConfig.getConfigs() != null) {
mergedConfig.setConfigs(newConfig.getConfigs());
}
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())) {View on GitHub (pinned to 820761864e)
Solutions
- Keep retainKeyOrdering identical to the existing sink's value (or null)
- Delete and recreate the sink if key ordering must change
- Verify the deployed value via 'pulsar-admin sinks get' before updating
Example fix
// before sinkConfig.setRetainKeyOrdering(true); // deployed sink has false admin.sinks().updateSink(tenant, namespace, sinkConfig, null); // after sinkConfig.setRetainKeyOrdering(false); // matches existing admin.sinks().updateSink(tenant, namespace, sinkConfig, null);
Defensive patterns
Strategy: validation
Validate before calling
if (newCfg.getRetainKeyOrdering() != null
&& !newCfg.getRetainKeyOrdering().equals(existing.getRetainKeyOrdering())) {
throw new IllegalArgumentException("retainKeyOrdering is immutable");
} Try / catch
try {
admin.sinks().updateSink(tenant, namespace, cfg, null);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Retain Key Ordering cannot be altered")) { /* revert retainKeyOrdering */ }
else throw e;
} Prevention
- Leave retainKeyOrdering null on updates
- Recreate the sink if key ordering must change
- Document ordering decisions at creation time
When it happens
Trigger: Updating a sink with getRetainKeyOrdering() non-null and different from the deployed config's value.
Common situations: Enabling per-key ordering on an already deployed sink via update; a config template with retainKeyOrdering enabled is reused to update a sink created without it.
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/12bccf3757ead534.
Report an issue: GitHub.