{"record":{"id":"dca22e703100f614","repo":"apache/pulsar","slug":"could-not-instantiate-configkeyname-factorycla","errorCode":null,"errorMessage":"Could not instantiate <configKeyName> '<factoryClassName>'","messagePattern":"Could not instantiate <configKeyName> '<factoryClassName>'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/tls/ClientTlsFactorySupport.java","lineNumber":341,"sourceCode":"     * Reflectively instantiate a named {@link PulsarTlsFactory} via its public no-arg constructor, failing\n     * loudly (an {@link IllegalArgumentException} naming the config key) when it cannot be instantiated.\n     *\n     * @param factoryClassName the factory class name to instantiate\n     * @param configKeyName    the config key naming it (for the failure message)\n     * @return the instantiated factory\n     */\n    static PulsarTlsFactory instantiateNamedFactory(String factoryClassName, String configKeyName) {\n        String name = factoryClassName.trim();\n        // FIX G: honor the thread context classloader (PulsarAdminImpl sets it to the plugin loader via\n        // setContextClassLoader) so a factory class visible only through a custom TCCL is found. Plain\n        // Class.forName(name) uses only this class's defining loader and misses TCCL-only classes. Fall back\n        // to the defining loader when no TCCL is set.\n        ClassLoader tccl = Thread.currentThread().getContextClassLoader();\n        try {\n            Class<?> clazz = tccl != null ? Class.forName(name, true, tccl) : Class.forName(name);\n            return (PulsarTlsFactory) clazz.getConstructor().newInstance();\n        } catch (ReflectiveOperationException e) {\n            throw new IllegalArgumentException(\n                    \"Could not instantiate \" + configKeyName + \" '\" + factoryClassName + \"'\", e);\n        }\n    }\n\n    /**\n     * Parse a {@code tlsFactoryConfig} string into the factory init params map (mirrors the server-side\n     * {@code TlsFactorySupport.parseFactoryConfig}). A blank value yields an empty map; a value starting with\n     * <code>{</code> is parsed as a JSON object; otherwise it is parsed as a comma-separated\n     * {@code key=value} list.\n     *\n     * @param tlsFactoryConfig the configured factory params (may be null/blank)\n     * @return an immutable params map (possibly empty)\n     */\n    static Map<String, String> parseFactoryConfig(String tlsFactoryConfig) {\n        if (StringUtils.isBlank(tlsFactoryConfig)) {\n            return Map.of();\n        }\n        String trimmed = tlsFactoryConfig.trim();","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/tls/ClientTlsFactorySupport.java#L323-L359","documentation":"instantiateNamedFactory loads a PulsarTlsFactory implementation class by name via Class.forName (preferring the thread context classloader) and instantiates it with a no-arg constructor. If the class cannot be loaded, is not a PulsarTlsFactory, lacks a no-arg constructor, or its constructor fails, an IllegalArgumentException is thrown naming the config key and class.","triggerScenarios":"Setting a client TLS factory config key (e.g. tlsFactoryClassName-style configKeyName) to a class name that does not exist, is abstract, has no public no-arg constructor, throws in its constructor, or is not visible to the TCCL.","commonSituations":"Typo in the fully-qualified class name; class not on the client classpath; custom factory with only a parameterized constructor; shaded/uber-jar excluding the factory class; factory constructor throwing due to bad init.","solutions":["Verify the fully-qualified class name in the config is correct and spelled exactly.","Ensure the factory class is on the client classpath and visible to the thread context classloader.","Give the factory a public no-arg constructor (parameterless) implementing PulsarTlsFactory.","Check the factory constructor for throwing code (bad config files, etc.) and fix its initialization."],"exampleFix":"// before\nclass MyTlsFactory implements PulsarTlsFactory {\n    public MyTlsFactory(String configPath) { ... }\n}\n// after\nclass MyTlsFactory implements PulsarTlsFactory {\n    public MyTlsFactory() { ... }\n    public void configure(Map<String,String> params) { ... }\n}","handlingStrategy":"validation","validationCode":"try {\n    Class<?> c = Class.forName(factoryClassName);\n    if (!PulsarTlsFactory.class.isAssignableFrom(c)) throw new IllegalArgumentException(\"not a PulsarTlsFactory\");\n    c.getDeclaredConstructor(); // must exist and be public\n} catch (ClassNotFoundException | NoSuchMethodException e) {\n    throw new IllegalArgumentException(\"Bad tls factory class: \" + factoryClassName, e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    buildClientWithTlsFactory(name);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Could not instantiate\")) {\n        log.error(\"Check class name, classpath, and no-arg constructor\", e);\n    }\n}","preventionTips":["Copy fully-qualified class names from the source, never retype","Ensure the factory class ships in your client jar/shaded artifact","Always implement a public no-arg constructor","Keep constructor side effects minimal; do config in init hooks"],"tags":["tls","reflection","config","instantiation"],"backgroundTag":"class-instantiation-failed","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"}