{"record":{"id":"aef660c097d3ab0b","repo":"apache/pulsar","slug":"only-one-of-retain-ordering-or-retain-key-ordering-aef660","errorCode":null,"errorMessage":"Only one of retain ordering or retain key ordering can be set","messagePattern":"Only one of retain ordering or retain key ordering can be set","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java","lineNumber":568,"sourceCode":"                }\n                if (consumerSpec.getMessagePayloadProcessorConfig() != null) {\n                    ValidatorUtils.validateMessagePayloadProcessor(consumerSpec.getMessagePayloadProcessorConfig(),\n                            inputFunction.getTypePool());\n                }\n            }\n        }\n\n        if (sinkConfig.getRetainKeyOrdering() != null\n                && sinkConfig.getRetainKeyOrdering()\n                && sinkConfig.getProcessingGuarantees() != null\n                && sinkConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {\n            throw new IllegalArgumentException(\n                    \"When effectively once processing guarantee is specified, retain Key ordering cannot be set\");\n        }\n\n        if (sinkConfig.getRetainKeyOrdering() != null && sinkConfig.getRetainKeyOrdering()\n                && sinkConfig.getRetainOrdering() != null && sinkConfig.getRetainOrdering()) {\n            throw new IllegalArgumentException(\"Only one of retain ordering or retain key ordering can be set\");\n        }\n\n        // validate user defined config if enabled and classloading is enabled\n        if (validateConnectorConfig) {\n            if (sinkFunction.isEnableClassloading()) {\n                validateSinkConfig(sinkConfig, sinkFunction);\n            } else {\n                log.warn(\"Skipping annotation based validation of sink config as classloading is disabled\");\n            }\n        }\n\n        return new ExtractedSinkDetails(sinkClassName, typeArg.asErasure().getTypeName(), functionClassName);\n    }\n\n    public static Collection<String> collectAllInputTopics(SinkConfig sinkConfig) {\n        List<String> retval = new LinkedList<>();\n        if (sinkConfig.getInputs() != null) {\n            retval.addAll(sinkConfig.getInputs());","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java#L550-L586","documentation":"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.","triggerScenarios":"sinkConfig.retainKeyOrdering == true AND sinkConfig.retainOrdering == true during validateAndExtractDetails.","commonSituations":"Merging config templates that each set one flag; misunderstanding the semantics and setting both hoping for 'more ordering'.","solutions":["Enable only one of retainOrdering or retainKeyOrdering"],"exampleFix":"// before\nsinkConfig.setRetainOrdering(true);\nsinkConfig.setRetainKeyOrdering(true);\n// after\nsinkConfig.setRetainOrdering(true);\nsinkConfig.setRetainKeyOrdering(false);","handlingStrategy":"validation","validationCode":"if (Boolean.TRUE.equals(config.getRetainKeyOrdering())\n    && Boolean.TRUE.equals(config.getRetainOrdering())) {\n  throw new IllegalStateException(\"Set only one of retainOrdering / retainKeyOrdering\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  admin.sinks().createSink(config, archive);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"retain ordering or retain key ordering\")) {\n    config.setRetainKeyOrdering(false); // keep global ordering\n  } else { throw e; }\n}","preventionTips":["Choose one ordering semantic per sink and document it","Do not merge ordering flags when combining config templates"],"tags":["pulsar-functions","sink","configuration","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}