{"record":{"id":"1490cda2d8b6ac5b","repo":"apache/pulsar","slug":"failed-to-create-instance-for-key-reader-class","errorCode":null,"errorMessage":"Failed to create instance for key reader class","messagePattern":"Failed to create instance for key reader class","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java","lineNumber":107,"sourceCode":"    }\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:\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:","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java#L89-L125","documentation":"CryptoUtils.getCryptoKeyReaderInstance reflectively instantiates a user-provided CryptoKeyReader class using its (java.util.Map) constructor. This error means the constructor exists (otherwise a NoSuchMethodException would be thrown) but invoking it failed — either the class is abstract/an interface and cannot be instantiated, the constructor threw an exception, or the class/constructor is not accessible. It wraps the underlying reflective failure in a RuntimeException.","triggerScenarios":"Calling getCryptoKeyReaderInstance(class, configs) with: an abstract class or interface implementing CryptoKeyReader (InstantiationException); a constructor that throws on the supplied configs map (InvocationTargetException); a non-public class/constructor without setAccessible (IllegalAccessException).","commonSituations":"Misconfigured function/crypto config pointing at the wrong class name or a class from an old artifact version; a key reader whose constructor throws because a required key/certificate path in configs is missing or unreadable (KMS/credentials unavailable); a package-private CryptoKeyReader implementation that isn't exported.","solutions":["Fix the user-supplied CryptoKeyReader implementation: make it a public, concrete (non-abstract) class with a public constructor accepting java.util.Map","Inspect the wrapped cause (getCause() of this RuntimeException — often InvocationTargetException) and fix whatever made the constructor throw (e.g. missing/invalid entries in the configs map, unreachable key service)","Ensure the class is on the function worker's classpath and the configured class name matches the deployed artifact version","Log configs keys and verify required parameters before constructing the reader"],"exampleFix":"// before\npublic class MyKeyReader implements CryptoKeyReader {\n    MyKeyReader(Map<String, String> configs) { ... } // package-private\n}\n// after\npublic class MyKeyReader implements CryptoKeyReader {\n    public MyKeyReader(Map<String, String> configs) { ... } // public, no-throw setup\n}","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(className);\nif (c.isInterface() || Modifier.isAbstract(c.getModifiers()))\n    throw new IllegalArgumentException(className + \" is not instantiable\");\nif (!CryptoKeyReader.class.isAssignableFrom(c))\n    throw new IllegalArgumentException(className + \" does not implement CryptoKeyReader\");\ntry {\n    Constructor<?> ctor = c.getConstructor(Map.class);\n    if (!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(c.getModifiers()))\n        throw new IllegalArgumentException(className + \" or its Map constructor is not public\");\n} catch (NoSuchMethodException e) {\n    throw new IllegalArgumentException(className + \" lacks a public (Map) constructor\");\n}\n// also pre-check any required keys your reader expects: configs.containsKey(\"keyPath\")","typeGuard":null,"tryCatchPattern":"try {\n    CryptoKeyReader reader = CryptoUtils.getCryptoKeyReaderInstance(cls, configs);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof InvocationTargetException)\n        log.error(\"Key reader constructor threw\", cause.getCause());\n    else if (cause instanceof InstantiationException)\n        log.error(\"Class is abstract/interface\", cause);\n    else\n        log.error(\"Inaccessible class/constructor\", cause);\n    throw new IllegalArgumentException(\"Invalid CryptoKeyReader class: \" + cls.getName(), e);\n}","preventionTips":["Make every CryptoKeyReader implementation public, concrete, with a public Map constructor","Keep constructor logic minimal; defer I/O (key loading) to the first decrypt call so construction never throws","Log the constructor's exception chain (cause.getCause() for InvocationTargetException) when diagnosing","Pin the artifact containing the reader to the version expected on the worker classpath"],"tags":["reflection","instantiation","crypto","configuration"],"backgroundTag":"reflective-class-instantiation-failed","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"}