apache/pulsar · error · IllegalArgumentException
Only one of retain ordering or retain key ordering can be se
Error message
Only one of retain ordering or retain key ordering can be set
What it means
SinkConfigUtils validates conflicting ordering options: both retain-ordering and retain-key-ordering were enabled (or the combination with effectively-once processing guarantees is invalid), but only one ordering mode may be set.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java:568
}
if (consumerSpec.getMessagePayloadProcessorConfig() != null) {
ValidatorUtils.validateMessagePayloadProcessor(consumerSpec.getMessagePayloadProcessorConfig(),
inputFunction.getTypePool());
}
}
}
if (sinkConfig.getRetainKeyOrdering() != null
&& sinkConfig.getRetainKeyOrdering()
&& sinkConfig.getProcessingGuarantees() != null
&& sinkConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {
throw new IllegalArgumentException(
"When effectively once processing guarantee is specified, retain Key ordering cannot be set");
}
if (sinkConfig.getRetainKeyOrdering() != null && sinkConfig.getRetainKeyOrdering()
&& sinkConfig.getRetainOrdering() != null && sinkConfig.getRetainOrdering()) {
throw new IllegalArgumentException("Only one of retain ordering or retain key ordering can be set");
}
// validate user defined config if enabled and classloading is enabled
if (validateConnectorConfig) {
if (sinkFunction.isEnableClassloading()) {
validateSinkConfig(sinkConfig, sinkFunction);
} else {
log.warn("Skipping annotation based validation of sink config as classloading is disabled");
}
}
return new ExtractedSinkDetails(sinkClassName, typeArg.asErasure().getTypeName(), functionClassName);
}
public static Collection<String> collectAllInputTopics(SinkConfig sinkConfig) {
List<String> retval = new LinkedList<>();
if (sinkConfig.getInputs() != null) {
retval.addAll(sinkConfig.getInputs());View on GitHub (pinned to 820761864e)
Solutions
- Enable only one of retainOrdering or retainKeyOrdering
Example fix
// before sinkConfig.setRetainOrdering(true); sinkConfig.setRetainKeyOrdering(true); // after sinkConfig.setRetainOrdering(true); sinkConfig.setRetainKeyOrdering(false);
Defensive patterns
Strategy: validation
Validate before calling
if (Boolean.TRUE.equals(config.getRetainKeyOrdering())
&& Boolean.TRUE.equals(config.getRetainOrdering())) {
throw new IllegalStateException("Set only one of retainOrdering / retainKeyOrdering");
} Try / catch
try {
admin.sinks().createSink(config, archive);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("retain ordering or retain key ordering")) {
config.setRetainKeyOrdering(false); // keep global ordering
} else { throw e; }
} Prevention
- Choose one ordering semantic per sink and document it
- Do not merge ordering flags when combining config templates
When it happens
Trigger: sinkConfig.retainKeyOrdering == true AND sinkConfig.retainOrdering == true during validateAndExtractDetails.
Common situations: Merging config templates that each set one flag; misunderstanding the semantics and setting both hoping for 'more ordering'.
Related errors
- Only one of serdeClassName or schemaType should be set
- When effectively once processing guarantee is specified, ret
- Sink class %s does not implement the correct interface
- Function config is not provided
- Output topic %s is also being used as an input topic (topics
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/aef660c097d3ab0b.
Report an issue: GitHub.