apache/pulsar · error · IllegalArgumentException
Processing Guarantees cannot be altered
Error message
Processing Guarantees cannot be altered
What it means
Processing guarantees (ATLEAST_ONCE, ATMOST_ONCE, EFFECTIVELY_ONCE) are delivery-semantics set at creation and cannot be changed on update, since they affect the function's subscription and state management behavior. validateUpdate throws when the new config specifies a non-null processingGuarantees that differs from the existing one.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:1067
"isRegexPattern for input topic " + topicName + " cannot be altered");
}
mergedConfig.getInputSpecs().put(topicName, consumerConfig);
});
}
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());
}View on GitHub (pinned to 820761864e)
Solutions
- Leave processingGuarantees unset (null) in the update payload, or set it exactly to the existing value.
- If guarantees must change, delete and recreate the function with the new ProcessingGuarantees value.
- Check deploy tooling for hardcoded processingGuarantees defaults that differ from the original creation.
Example fix
// before newConfig.setProcessingGuarantees(ProcessingGuarantees.EFFECTIVELY_ONCE); // existing: ATLEAST_ONCE // after newConfig.setProcessingGuarantees(null); // keep existing guarantee on update // or recreate the function with EFFECTIVELY_ONCE
Defensive patterns
Strategy: validation
Validate before calling
if (newConfig.getProcessingGuarantees() != null
&& !newConfig.getProcessingGuarantees().equals(existingConfig.getProcessingGuarantees())) {
throw new IllegalArgumentException("processingGuarantees is immutable on update");
} Type guard
boolean guaranteesUnchanged(FunctionConfig existing, FunctionConfig updated) {
return updated.getProcessingGuarantees() == null
|| updated.getProcessingGuarantees().equals(existing.getProcessingGuarantees());
} Try / catch
try {
merged = FunctionConfigUtils.validateUpdate(existing, updated);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Processing Guarantees cannot be altered")) {
updated.setProcessingGuarantees(null);
merged = FunctionConfigUtils.validateUpdate(existing, updated);
} else { throw e; }
} Prevention
- Omit processingGuarantees from update payloads; set it only at creation.
- Avoid hardcoded delivery-guarantee defaults in deploy tooling.
- Recreate the function when delivery semantics must change.
When it happens
Trigger: Updating a function with newConfig.getProcessingGuarantees() != null and != existingConfig.getProcessingGuarantees(), e.g. switching ATLEAST_ONCE to EFFECTIVELY_ONCE.
Common situations: Trying to tighten/loosen delivery guarantees on a live function to fix duplicate or lost message concerns; config templates that always set processingGuarantees; migrations from at-most-once to at-least-once processing.
Related errors
- Tenants differ
- Namespaces differ
- Function Names differ
- Input Topics cannot be altered
- isRegexPattern for input topic
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/32bd19c571caf228.
Report an issue: GitHub.