apache/pulsar · error · IllegalArgumentException
Retain Key Ordering cannot be altered
Error message
Retain Key Ordering cannot be altered
What it means
validateUpdate treats retainKeyOrdering as an immutable function property. Updating a function with a different retainKeyOrdering value than the existing one throws IllegalArgumentException, because key-ordering semantics cannot be changed for an already-registered function.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:1075
}
if (!StringUtils.isEmpty(newConfig.getOutputSchemaType()) && !newConfig.getOutputSchemaType()
.equals(existingConfig.getOutputSchemaType())) {
throw new IllegalArgumentException("Output Schema mismatch");
}
if (!StringUtils.isEmpty(newConfig.getLogTopic())) {
mergedConfig.setLogTopic(newConfig.getLogTopic());
}
if (newConfig.getProcessingGuarantees() != null && !newConfig.getProcessingGuarantees()
.equals(existingConfig.getProcessingGuarantees())) {
throw new IllegalArgumentException("Processing Guarantees cannot be altered");
}
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");
}
if (!StringUtils.isEmpty(newConfig.getOutput())) {
mergedConfig.setOutput(newConfig.getOutput());
}
if (newConfig.getUserConfig() != null) {
mergedConfig.setUserConfig(newConfig.getUserConfig());
}
if (newConfig.getSecrets() != null) {
mergedConfig.setSecrets(newConfig.getSecrets());
}
if (newConfig.getRuntime() != null && !newConfig.getRuntime().equals(existingConfig.getRuntime())) {
throw new IllegalArgumentException("Runtime cannot be altered");
}
@SuppressWarnings("deprecation")
boolean autoAckChanged = newConfig.getAutoAck() != null
&& !newConfig.getAutoAck().equals(existingConfig.getAutoAck());
if (autoAckChanged) {
throw new IllegalArgumentException("AutoAck cannot be altered");View on GitHub (pinned to 820761864e)
Solutions
- Leave retainKeyOrdering as-is (null or equal to the existing value) in the update request.
- Delete and re-create the function if key-ordering behavior must change.
- Fetch the current config with getFunction and only modify allowed fields before submitting.
Example fix
// before newConfig.setRetainKeyOrdering(true); // existing was false -> thrown // after newConfig.setRetainKeyOrdering(null); // or keep existing value
Defensive patterns
Strategy: validation
Validate before calling
FunctionConfig existing = admin.functions().getFunction(tenant, namespace, fnName);
if (update.getRetainKeyOrdering() != null && !update.getRetainKeyOrdering().equals(existing.getRetainKeyOrdering())) {
update.setRetainKeyOrdering(null);
} Try / catch
try {
admin.functions().updateFunction(update, pkgFile);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Retain Key Ordering")) { /* clear field and retry */ }
else throw e;
} Prevention
- Treat retainKeyOrdering as create-only; never set it in updates.
- Build update configs from the fetched existing config.
- Document immutable fields in any internal deploy tooling.
When it happens
Trigger: Calling updateFunction with a FunctionConfig where getRetainKeyOrdering() is non-null and does not equal the existing config's value.
Common situations: Toggling key ordering while debugging out-of-order keyed messages; update payloads generated from templates that set retainKeyOrdering explicitly and differ from the deployed function.
Related errors
- Retain Ordering cannot be altered
- Tenants differ
- Namespaces differ
- Function Names differ
- Input Topics cannot be altered
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/76f788b2e262fe5a.
Report an issue: GitHub.