{"record":{"id":"1b63ffffd54b1425","repo":"apache/pulsar","slug":"unable-to-initialize-crypto-config-s","errorCode":null,"errorMessage":"Unable to initialize crypto config %s","messagePattern":"Unable to initialize crypto config (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ProducerBuilderFactory.java","lineNumber":62,"sourceCode":" * and this class is used to unify the configuration of the producers without duplicating code.\n */\n@CustomLog\npublic class ProducerBuilderFactory {\n\n    private final PulsarClient client;\n    private final ProducerConfig producerConfig;\n    private final Consumer<ProducerBuilder<?>> defaultConfigurer;\n    private final Crypto crypto;\n\n    public ProducerBuilderFactory(PulsarClient client, ProducerConfig producerConfig, ClassLoader functionClassLoader,\n                                  Consumer<ProducerBuilder<?>> defaultConfigurer) {\n        this.client = client;\n        this.producerConfig = producerConfig;\n        this.defaultConfigurer = defaultConfigurer;\n        try {\n            this.crypto = initializeCrypto(functionClassLoader);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(\"Unable to initialize crypto config \" + producerConfig.getCryptoConfig(), e);\n        }\n        if (crypto == null) {\n            log.info(\"crypto key reader is not provided, not enabling end to end encryption\");\n        }\n    }\n\n    @SuppressWarnings(\"deprecation\")\n    public <T> ProducerBuilder<T> createProducerBuilder(String topic, Schema<T> schema, String producerName) {\n        ProducerBuilder<T> builder = client.newProducer(schema);\n        if (defaultConfigurer != null) {\n            defaultConfigurer.accept(builder);\n        }\n        builder.blockIfQueueFull(true)\n                .enableBatching(true)\n                .batchingMaxPublishDelay(10, TimeUnit.MILLISECONDS)\n                .hashingScheme(HashingScheme.Murmur3_32Hash) //\n                .messageRoutingMode(MessageRoutingMode.CustomPartition)\n                .messageRouter(FunctionResultRouter.of())","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ProducerBuilderFactory.java#L44-L80","documentation":"ProducerBuilderFactory loads the user's crypto key reader class from the function classloader (initializeCrypto) based on the producer's cryptoConfig. If the configured class name cannot be found (ClassNotFoundException), the builder cannot construct the end-to-end encryption machinery and throws RuntimeException embedding the cryptoConfig string.","triggerScenarios":"producerConfig.cryptoConfig.readerClassName names a class not present in the function JAR or its dependencies; typo in the class name; the crypto key reader class is shaded/relocated; crypto configured but the JAR with the key reader was not uploaded.","commonSituations":"Enabling end-to-end encryption on a sink/producer function whose key reader library isn't bundled; renaming the key reader class after an upgrade without updating function config; shade plugin relocating the crypto package; fat JAR missing optional crypto dependencies.","solutions":["Verify readerClassName matches a fully-qualified class that exists in the uploaded function JAR (unzip -l and check)","Add the crypto key reader implementation and its dependencies to the function JAR and redeploy","If encryption is not needed, remove the cryptoConfig from the producer config so the builder skips crypto (logged as 'crypto key reader is not provided')","Check shade plugin relocations — un-relocate the key reader package or update the configured class name"],"exampleFix":"// before\nProducerConfig cfg = ProducerConfig.newBuilder()\n    .setCryptoConfig(\"{\\\"readerClassName\\\":\\\"com.acme.OldKeyReader\\\"}\").build();\n// after\nProducerConfig cfg = ProducerConfig.newBuilder()\n    .setCryptoConfig(\"{\\\"readerClassName\\\":\\\"com.acme.BuiltinKeyReader\\\"}\").build();","handlingStrategy":"validation","validationCode":"String readerClass = extractReaderClassName(producerConfig.getCryptoConfig());\nClass.forName(readerClass, true, functionClassLoader); // fails fast if missing","typeGuard":null,"tryCatchPattern":"try { new ProducerBuilderFactory(client, fn, pc, cc, cl); }\ncatch (RuntimeException e) {\n  if (e.getMessage().startsWith(\"Unable to initialize crypto config\")) {\n    log.error(\"Check readerClassName exists in the function JAR\", e.getCause());\n  }\n}","preventionTips":["Bundle the crypto key reader class and its dependencies in the function JAR","Keep readerClassName in sync across refactors and shade relocations","Remove cryptoConfig when encryption is not actually required","Smoke-test producer creation with crypto locally before deploying"],"tags":["java","pulsar-functions","crypto","class-not-found","producer"],"backgroundTag":"class-not-found","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}