{"id":"71c2f8ec12adc991","repo":"apache/kafka","slug":"unexpected-element-of-type-klass-getclass-getnam","errorCode":null,"errorMessage":"Unexpected element of type klass.getClass().getName(), expected String or Class","messagePattern":"Unexpected element of type klass\\.getClass\\(\\)\\.getName\\(\\), expected String or Class","errorType":"exception","errorClass":"KafkaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/config/AbstractConfig.java","lineNumber":413,"sourceCode":"            log.info(\"These configurations '{}' were supplied but are not used yet.\", unusedKeys);\n        }\n    }\n\n    private <T> T getConfiguredInstance(Object klass, Class<T> t, Map<String, Object> configPairs) {\n        if (klass == null)\n            return null;\n        Object o;\n\n        if (klass instanceof String) {\n            try {\n                o = Utils.newInstance((String) klass, t);\n            } catch (ClassNotFoundException e) {\n                throw new KafkaException(\"Class \" + klass + \" cannot be found\", e);\n            }\n        } else if (klass instanceof Class<?>) {\n            o = Utils.newInstance((Class<?>) klass);\n        } else\n            throw new KafkaException(\"Unexpected element of type \" + klass.getClass().getName() + \", expected String or Class\");\n        try {\n            if (!t.isInstance(o))\n                throw new KafkaException(klass + \" is not an instance of \" + t.getName());\n            if (o instanceof Configurable)\n                ((Configurable) o).configure(configPairs);\n        } catch (Exception e) {\n            maybeClose(o, \"AutoCloseable object constructed and configured during failed call to getConfiguredInstance\");\n            throw e;\n        }\n        return t.cast(o);\n    }\n\n    /**\n     * Get a configured instance of the give class specified by the given configuration key. If the object implements\n     * Configurable configure it using the configuration.\n     *\n     * @param key The configuration key for the class\n     * @param t   The interface the class should implement","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/config/AbstractConfig.java#L395-L431","documentation":"KafkaException thrown by getConfiguredInstance(Object klass, Class<T> t, ...) when the `klass` argument is neither a String (class name) nor a Class<?> object. The method only knows how to instantiate from those two forms; any other Java type (e.g. a pre-instantiated object, a Map, an Integer) is rejected. This guard runs before any reflection, so it indicates a caller passing the wrong kind of value into the instance-resolution machinery.","triggerScenarios":"Most realistic path is getConfiguredInstances(List<String> classNames, ...) where the list unexpectedly contains a non-String element (e.g. a List<Object> built from heterogeneous config, or a parsed JSON array mixing types), causing the per-element dispatch to fall into the `else` branch. Also possible when application code calls the package-private getConfiguredInstance directly with an arbitrary object.","commonSituations":"See trigger scenarios.","solutions":["Ensure the value passed for a class-name config is a String (FQCN) or a Class<?>; for getConfiguredInstances the list elements must all be Strings.","If a config provider / external source is returning typed objects, convert them to class-name strings before they reach getConfiguredInstance.","Audit the list/element source (the message reports the actual Java type via klass.getClass().getName()) and fix the producer of that list.","Avoid passing pre-instantiated objects where the API expects a class name; register the class name instead."],"exampleFix":"// before: list contains a non-String element\nList<Object> elems = Arrays.asList(\"com.foo.A\", alreadyConstructedObject);\nconfig.getConfiguredInstances(elems, Plugin.class, Map.of()); // throws: type of the object\n\n// after\nList<String> elems = Arrays.asList(\"com.foo.A\", \"com.foo.B\");\nconfig.getConfiguredInstances(elems, Plugin.class, Map.of());","handlingStrategy":"type-guard","validationCode":"// Ensure the configured value is a String (class name) or a Class<?> before passing it in.\nObject configured = config.get(key);\nif (configured != null && !(configured instanceof String) && !(configured instanceof Class<?>)) {\n    throw new IllegalArgumentException(\n        \"Config '\" + key + \"' must be a class name (String) or Class<?>, got \" + configured.getClass().getName());\n}","typeGuard":"boolean isClassNameOrClass(Object v) {\n    return v == null || v instanceof String || v instanceof Class<?>;\n}","tryCatchPattern":"try {\n    T plugin = config.getConfiguredInstance(key, T.class);\n} catch (org.apache.kafka.common.KafkaException ke) {\n    if (ke.getMessage().contains(\"expected String or Class\")) {\n        // someone put an instance / numeric / boolean into a class-name config slot\n        log.error(\"Config '{}' is {}; expected FQCN or Class\", key, config.get(key).getClass());\n    } else {\n        throw ke;\n    }\n}","preventionTips":["Define pluggable settings in your ConfigDef with Type.CLASS or Type.STRING so parsed values are always a Class or FQCN string.","Never stash a pre-built instance into the config map expecting Kafka to accept it.","Validate at config-load time when the value originates from an untrusted source (e.g. env vars, REST API)."],"tags":["configuration","kafka-client","configdef","programming-error"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}