{"id":"49593ee756142e55","repo":"apache/kafka","slug":"class-value-could-not-be-found","errorCode":null,"errorMessage":"Class value could not be found.","messagePattern":"Class value could not be found\\.","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java","lineNumber":791,"sourceCode":"                            return List.of();\n                        else\n                            return Arrays.asList(COMMA_WITH_WHITESPACE.split(trimmed, -1));\n                    else\n                        throw new ConfigException(name, value, \"Expected a comma separated list.\");\n                case CLASS:\n                    if (value instanceof Class)\n                        return value;\n                    else if (value instanceof String) {\n                        return Utils.loadClass(trimmed, Object.class);\n                    } else\n                        throw new ConfigException(name, value, \"Expected a Class instance or class name.\");\n                default:\n                    throw new IllegalStateException(\"Unknown type.\");\n            }\n        } catch (NumberFormatException e) {\n            throw new ConfigException(name, value, \"Not a number of type \" + type);\n        } catch (ClassNotFoundException e) {\n            throw new ConfigException(name, value, \"Class \" + value + \" could not be found.\");\n        }\n    }\n\n    /**\n     * Convert the provided object into a string based on its type.\n     * <p>\n     * This method uses Java's {@link #toString()} for {@link Type#BOOLEAN}, {@link Type#SHORT}, {@link Type#INT},\n     * {@link Type#LONG}, {@link Type#DOUBLE}, {@link Type#STRING} and {@link Type#PASSWORD} objects.\n     * For {@link Type#LIST} objects, Java's {@link #toString()} is used for each entry and entries are concatenated\n     * separated by commas. For {@link Type#CLASS} objects, {@link Class#getName()} is used.\n     * @param parsedValue The object to convert into a string\n     * @param type The type of the object\n     * @return The string representation of the provided object and type\n     */\n    public static String convertToString(Object parsedValue, Type type) {\n        if (parsedValue == null) {\n            return null;\n        }","sourceCodeStart":773,"sourceCodeEnd":809,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java#L773-L809","documentation":"Catch block in ConfigDef.parseType wrapping a ClassNotFoundException raised by Utils.loadClass during the Type.CLASS branch. The library tried to resolve the supplied fully-qualified class name onto the classpath and the JVM could not find it. The thrown ConfigException echoes the offending value so the developer can see which class name failed to load.","triggerScenarios":"Setting a CLASS-typed config (key.serializer, value.deserializer, partitioner.class, sasl.client.callback.handler.class, security.providers, metric.reporters, client.dns.lookup custom impl, etc.) to an FQCN that is not present on the runtime classpath — typo, missing jar, wrong package, or class not public.","commonSituations":"Custom serializer/deserializer/partitioner in a separate module not packaged into the fat jar; Kafka Connect worker missing a converter plugin jar; shaded uber-jar that rewrote package names; typo in the FQCN; connector/plugin JAR installed in the wrong lib directory; class present only in test scope and not in the runtime artifact.","solutions":["Verify the class name spelling and package path against the actual jar (use jar tf / javap -classpath to confirm).","Ensure the jar containing the class is on the runtime classpath of the producer/consumer/broker/connect worker (e.g. Kafka libs dir, plugin.path for Connect, uber-jar for Streams).","If using a shade/relocate plugin, use the relocated package name in the config.","Make sure the class is public and (for serializers/deserializers/converters) has a public no-arg constructor.","Re-package and redeploy: a stale deployment without the new jar is the most common cause after an upgrade."],"exampleFix":"// before\nprops.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,\n         \"com.acme.InvalidSerializer\"); // typo -> ClassNotFoundException\n\n// after\nprops.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,\n         \"com.acme.InventorySerializer\");","handlingStrategy":"validation","validationCode":"if (value instanceof String) {\n    String cls = ((String) value).trim();\n    try {\n        Class.forName(cls, false, Thread.currentThread().getContextClassLoader());\n    } catch (ClassNotFoundException cnfe) {\n        throw new IllegalArgumentException(\"Class '\" + cls + \"' is not on the classpath\", cnfe);\n    }\n}","typeGuard":"public static boolean isClassLoadable(String className) {\n    try {\n        Class.forName(className, false, Thread.currentThread().getContextClassLoader());\n        return true;\n    } catch (Throwable t) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    configDef.parse(configs);\n} catch (ConfigException e) {\n    if (e.getMessage().contains(\"could not be found\")) {\n        // ensure the plugin jar is on the classpath / plugin.path, then retry\n    } else throw e;\n}","preventionTips":["For plugin-style CLASS config (serdes, partitioners), confirm the jar is deployed and on the client classpath.","Use the fully-qualified name; avoid relying on imports or default packages.","Validate class availability at startup, not at first message."],"tags":["config","class-loading","classpath","plugin","serializer","client"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}