apache/pulsar · error · IllegalArgumentException
Retain Ordering cannot be altered
Error message
Retain Ordering cannot be altered
What it means
FunctionConfigUtils.validateUpdate enforces that certain function settings are immutable after creation. retainOrdering changes would require a new subscription/consumption mode on the existing topic, so Pulsar rejects the update with IllegalArgumentException instead of applying it.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:1071
}
if (!StringUtils.isEmpty(newConfig.getOutputSerdeClassName()) && !newConfig.getOutputSerdeClassName()
.equals(existingConfig.getOutputSerdeClassName())) {
throw new IllegalArgumentException("Output Serde mismatch");
}
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")View on GitHub (pinned to 820761864e)
Solutions
- Keep retainOrdering unchanged in the update request (pass null or the existing value fetched via getFunction).
- If a different retainOrdering is truly needed, delete and re-create (or re-register) the function with the new value.
- Diff the new config against the current config before submitting to catch the conflicting field.
- Check client SDK/tooling defaults so retainOrdering is not implicitly set on updates.
Example fix
// before FunctionConfig update = existing; update.setRetainOrdering(!existing.getRetainOrdering()); // rejected admin.functions().updateFunction(update, configFile); // after FunctionConfig update = existing; update.setRetainOrdering(existing.getRetainOrdering()); // unchanged, or leave null admin.functions().updateFunction(update, configFile);
Defensive patterns
Strategy: validation
Validate before calling
FunctionConfig existing = admin.functions().getFunction(tenant, namespace, fnName);
if (update.getRetainOrdering() != null && !update.getRetainOrdering().equals(existing.getRetainOrdering())) {
update.setRetainOrdering(null); // drop immutable change
} Try / catch
try {
admin.functions().updateFunction(update, pkgFile);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("cannot be altered")) { /* reset immutable fields and retry once */ }
else throw e;
} Prevention
- Always fetch the current config with getFunction and modify only allowed fields.
- Leave immutable fields null in update requests instead of copying defaults.
- Diff the update against the existing config before submitting.
- Re-create the function instead of updating when ordering semantics must change.
When it happens
Trigger: Calling updateFunction (or the PUT admin API) with a FunctionConfig whose getRetainOrdering() is non-null and differs from the existing function's retainOrdering.
Common situations: Submitting an updated function config where the caller populated retainOrdering=true by default or changed it to fix ordering issues; client tooling that always serializes all fields, turning an unset field into an explicit conflicting value.
Related errors
- Retain Key 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/71899f39b174683c.
Report an issue: GitHub.