{"record":{"id":"6b67a59b8b9cbf48","repo":"apache/pulsar","slug":"unknown-producer-protobuf-failure-action","errorCode":null,"errorMessage":"Unknown producer protobuf failure action ","messagePattern":"Unknown producer protobuf failure action ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java","lineNumber":118,"sourceCode":"\n        try {\n            Constructor<?> ctor = cryptoClass.getConstructor(Map.class);\n            return (CryptoKeyReader) ctor.newInstance(configs);\n        } catch (NoSuchMethodException e) {\n            throw new RuntimeException(\"Key reader class does not have constructor accepts map\", e);\n        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {\n            throw new RuntimeException(\"Failed to create instance for key reader class\", e);\n        }\n    }\n\n    public static ProducerCryptoFailureAction getProducerCryptoFailureAction(CryptoSpec.FailureAction action) {\n        switch (action) {\n            case FAIL:\n                return ProducerCryptoFailureAction.FAIL;\n            case SEND:\n                return ProducerCryptoFailureAction.SEND;\n            default:\n                throw new RuntimeException(\n                        \"Unknown producer protobuf failure action \" + action.name());\n        }\n    }\n\n    public static ConsumerCryptoFailureAction getConsumerCryptoFailureAction(CryptoSpec.FailureAction action) {\n        switch (action) {\n            case FAIL:\n                return ConsumerCryptoFailureAction.FAIL;\n            case DISCARD:\n                return ConsumerCryptoFailureAction.DISCARD;\n            case CONSUME:\n                return ConsumerCryptoFailureAction.CONSUME;\n            default:\n                throw new RuntimeException(\n                        \"Unknown consumer protobuf failure action \" + action.name());\n        }\n    }\n","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java#L100-L136","documentation":"CryptoUtils.getProducerCryptoFailureAction maps a CryptoSpec.FailureAction enum value to the client's ProducerCryptoFailureAction. The switch handles FAIL and SEND; any other value is unsupported and triggers this RuntimeException with the offending enum name appended. It indicates a failure-action value outside the supported producer set reached the converter.","triggerScenarios":"Calling getProducerCryptoFailureAction with a CryptoSpec.FailureAction value other than FAIL or SEND — e.g. a consumer-only action such as DISCARD or CONSUME passed into the producer-side converter, or a newly added enum value from a newer Pulsar version processed by an older converter.","commonSituations":"Copying a consumer crypto spec into a producer config; hand-written YAML/JSON function configs where the action name is for the consumer side; version skew between client library and functions utils after new enum constants were added.","solutions":["Set the producer's CryptoSpec failureAction to FAIL or SEND only","If you copied config from a consumer, switch to getConsumerCryptoFailureAction or use consumer-appropriate values (DISCARD/CONSUME)","Align library versions so the enum sets match between the config producer and this converter"],"exampleFix":"// before\ncryptoSpec.setFailureAction(CryptoSpec.FailureAction.DISCARD); // consumer-only\n// after\ncryptoSpec.setFailureAction(CryptoSpec.FailureAction.SEND); // valid for producer","handlingStrategy":"validation","validationCode":"if (action != CryptoSpec.FailureAction.FAIL && action != CryptoSpec.FailureAction.SEND) {\n    throw new IllegalArgumentException(\"Producer failureAction must be FAIL or SEND, got \" + action);\n}","typeGuard":"boolean isProducerAction(CryptoSpec.FailureAction a) {\n    return a == CryptoSpec.FailureAction.FAIL || a == CryptoSpec.FailureAction.SEND;\n}","tryCatchPattern":"try {\n    ProducerCryptoFailureAction mapped = CryptoUtils.getProducerCryptoFailureAction(action);\n} catch (RuntimeException e) {\n    log.warn(\"Unsupported producer failure action, defaulting to FAIL\", e);\n    ProducerCryptoFailureAction mapped = ProducerCryptoFailureAction.FAIL;\n}","preventionTips":["Only set FAIL or SEND in producer crypto specs","Never copy consumer-side action values into producer specs","Keep client and broker Pulsar versions aligned","Add config validation at submission time, not conversion time"],"tags":["enum","crypto","configuration","mapping"],"backgroundTag":"unsupported-enum-value","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"}