{"record":{"id":"b9291b6b70eb3e85","repo":"apache/pulsar","slug":"failed-to-load-crypto-key-reader-class-sx","errorCode":null,"errorMessage":"Failed to load crypto key reader class %sx","messagePattern":"Failed to load crypto key reader class (.+?)x","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java","lineNumber":97,"sourceCode":"            keyNames.add(spec.getProducerEncryptionKeyNameAt(i));\n        }\n\n        bldr.cryptoKeyReaderClassName(spec.getCryptoKeyReaderClassName())\n                .cryptoKeyReaderConfig(cryptoReaderConfig)\n                .consumerCryptoFailureAction(getConsumerCryptoFailureAction(spec.getConsumerCryptoFailureAction()))\n                .producerCryptoFailureAction(getProducerCryptoFailureAction(spec.getProducerCryptoFailureAction()))\n                .encryptionKeys(keyNames.toArray(new String[0]));\n\n        return bldr.build();\n    }\n\n    public static CryptoKeyReader getCryptoKeyReaderInstance(String className, Map<String, Object> configs,\n                                                             ClassLoader classLoader) {\n        Class<?> cryptoClass;\n        try {\n            cryptoClass = ClassLoaderUtils.loadClass(className, classLoader);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(\n                    String.format(\"Failed to load crypto key reader class %sx\", className));\n        }\n\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:","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java#L79-L115","documentation":"CryptoUtils.getCryptoKeyReaderInstance loads a CryptoKeyReader implementation class by name using the provided classloader and instantiates it. If ClassLoaderUtils.loadClass cannot find the class (ClassNotFoundException), it throws this RuntimeException — note the message appends a stray 'x' after the class name ('...class com.foo.MyReaderx').","triggerScenarios":"Producer/Consumer/Reader crypto config specifies cryptoKeyReaderClassName for a class not on the classpath of the client/connector, e.g. a typo in the fully-qualified name, or the jar containing the implementation was never added to the client's/worker's classpath.","commonSituations":"fat-jar for a Pulsar IO connector not including the custom CryptoKeyReader class; class name changed after refactoring/upgrade; running the client with a shaded classloader where the crypto class lives in a different jar.","solutions":["Correct the fully-qualified class name in the crypto config (also verify no trailing whitespace/newline)","Add the jar containing the CryptoKeyReader implementation to the classpath (client -cp, connector's extra deps directory, or fat jar)","Verify the class implements org.apache.pulsar.client.api.CryptoKeyReader and is public"],"exampleFix":"// before\nMap<String,String> m = new HashMap<>();\nm.put(\"cryptoKeyReaderClassName\", \"com.example.MyCryptoReader\"); // class not in jar\n// after\nm.put(\"cryptoKeyReaderClassName\", \"com.example.crypto.MyCryptoKeyReader\");\n// and: add target/my-crypto-impl.jar to the connector's extra deps or client classpath","handlingStrategy":"try-catch","validationCode":"try {\n    Class.forName(cryptoKeyReaderClassName, true, classLoader);\n} catch (ClassNotFoundException e) {\n    throw new IllegalStateException(\"CryptoKeyReader class not on classpath: \" + cryptoKeyReaderClassName);\n}","typeGuard":null,"tryCatchPattern":"try {\n    CryptoKeyReader reader = CryptoUtils.getCryptoKeyReaderInstance(className, configs, classLoader);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Failed to load crypto key reader class\")) { /* fix class name / add jar */ }\n}","preventionTips":["Verify the FQCN with Class.forName or javap before configuring it","Ensure the crypto implementation jar ships in the connector's extra-deps or client classpath","Grep the deployment bundle for the class file to confirm packaging"],"tags":["classpath","crypto","classloading","pulsar-client"],"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"}