{"record":{"id":"e24795496a2ac091","repo":"apache/pulsar","slug":"when-effectively-once-processing-guarantee-is-spec-e24795","errorCode":null,"errorMessage":"When effectively once processing guarantee is specified, retain Key ordering cannot be set","messagePattern":"When effectively once processing guarantee is specified, retain Key ordering cannot 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":562,"sourceCode":"                    ValidatorUtils.validateSchema(consumerSpec.getSchemaType(), typeArg,\n                            inputFunction.getTypePool(), true);\n                }\n                if (consumerSpec.getCryptoConfig() != null) {\n                    ValidatorUtils.validateCryptoKeyReader(consumerSpec.getCryptoConfig(),\n                            inputFunction.getTypePool(), false);\n                }\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);","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java#L544-L580","documentation":"Retain-key-ordering requires keyed (non-effectively-once) processing semantics; combining EFFECTIVELY_ONCE processing guarantees with retainKeyOrdering=true is rejected as semantically contradictory by the sink validation.","triggerScenarios":"sinkConfig.retainKeyOrdering == true AND processingGuarantees == EFFECTIVELY_ONCE at sink create time.","commonSituations":"Copying a function config tuned for at-least-once ordered delivery into an exactly-once sink; toggling processingGuarantees to EFFECTIVELY_ONCE without clearing retainKeyOrdering.","solutions":["Set retainKeyOrdering to false/null when using EFFECTIVELY_ONCE","Or use ATLEAST_ONCE processing guarantees if key ordering retention is required"],"exampleFix":"// before\nsinkConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE);\nsinkConfig.setRetainKeyOrdering(true);\n// after\nsinkConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE);\nsinkConfig.setRetainKeyOrdering(false);","handlingStrategy":"validation","validationCode":"if (Boolean.TRUE.equals(config.getRetainKeyOrdering())\n    && config.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {\n  throw new IllegalStateException(\"retainKeyOrdering incompatible with EFFECTIVELY_ONCE\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  admin.sinks().createSink(config, archive);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"retain Key ordering cannot be set\")) {\n    config.setRetainKeyOrdering(false);\n  } else { throw e; }\n}","preventionTips":["Treat retainKeyOrdering as at-least-once only","Reset ordering flags when changing processingGuarantees"],"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"}