{"record":{"id":"88df2a218f7bf7a3","repo":"apache/hadoop","slug":"readobject-can-t-find-class-classname","errorCode":null,"errorMessage":"readObject can't find class {className}","messagePattern":"readObject can't find class (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/ObjectWritable.java","lineNumber":420,"sourceCode":"\n  /**\n   * Find and load the class with given name <code>className</code> by first finding\n   * it in the specified <code>conf</code>. If the specified <code>conf</code> is null,\n   * try load it directly.\n   *\n   * @param conf configuration.\n   * @param className classname.\n   * @return Class.\n   */\n  public static Class<?> loadClass(Configuration conf, String className) {\n    Class<?> declaredClass = null;\n    try {\n      if (conf != null)\n        declaredClass = conf.getClassByName(className);\n      else\n        declaredClass = Class.forName(className);\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"readObject can't find class \" + className,\n          e);\n    }\n    return declaredClass;\n  }\n\n  @Override\n  public void setConf(Configuration conf) {\n    this.conf = conf;\n  }\n\n  @Override\n  public Configuration getConf() {\n    return this.conf;\n  }\n  \n}\n","sourceCodeStart":402,"sourceCodeEnd":437,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/ObjectWritable.java#L402-L437","documentation":"Thrown by ObjectWritable.loadClass(Configuration, String) when the class named in the serialized stream cannot be resolved: Configuration.getClassByName(className) (or Class.forName when conf is null) raises ClassNotFoundException, which is rethrown as this RuntimeException. ObjectWritable stores the concrete class NAME inside the stream for Writable values; on read, that class must exist on the reader's classpath.","triggerScenarios":"Deserializing an ObjectWritable/RPC payload whose embedded class name (e.g. com.example.MyWritable) is absent from the reading JVM's classpath; running with conf == null so only Class.forName on the system classloader is used; class renamed/moved between writer and reader versions.","commonSituations":"Client JVM missing the application jar that defines custom Writable types used in RPC responses; Hadoop/dependency version skew where a class moved packages; shaded/relocated jars changing class names; distributed cache not shipping the job jar to nodes doing the deserialization.","solutions":["Add the jar containing the named class to the reader's classpath (cluster client classpath, job jar lib/, or DistributedCache).","Align Hadoop/dependency versions between writer and reader if the class moved between versions.","If you renamed the class, either keep a serialization-compatible alias or rewrite the data.","Pass a non-null Configuration so class resolution uses the Hadoop classpath (conf.getClassByName) rather than only the system classloader."],"exampleFix":"// before: reading fails, class only on writer's classpath\nObjectWritable ow = new ObjectWritable();\now.setConf(conf);\now.readFields(in); // RuntimeException: readObject can't find class com.example.MyValue\n\n// after: ship and register the jar before deserializing\njob.addFileToClassPath(new Path(\"/libs/mytypes-1.0.jar\"), fs, conf);\n// or on a client: java -cp mytypes-1.0.jar:hadoop-classpath ...","handlingStrategy":"validation","validationCode":"try {\n  conf.getClassByName(className); // or ObjectWritable.loadClass(conf, className)\n} catch (ClassNotFoundException e) {\n  throw new IllegalStateException(\n      \"Class \" + className + \" from payload missing on this JVM — \"\n      + \"add its jar to the classpath/job jar\", e);\n}\n// safe to readFields now","typeGuard":"static boolean isClassResolvable(Configuration conf, String className) {\n  try {\n    ObjectWritable.loadClass(conf, className);\n    return true;\n  } catch (RuntimeException e) {\n    return e.getCause() instanceof ClassNotFoundException ? false : true; // rethrow others\n  }\n}","tryCatchPattern":"try {\n  ObjectWritable ow = new ObjectWritable();\n  ow.setConf(conf);\n  ow.readFields(in);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"readObject can't find class\")) {\n    failWithClasspathHint(e.getMessage()); // name the missing class and expected jar\n  }\n  throw e;\n}","preventionTips":["Ship all custom Writable classes in the job jar's lib/ and via DistributedCache so every node can resolve them.","Pass a Configuration into the read path (never null) so Hadoop's classpath is used, not just the system classloader.","When renaming/moving classes, keep data compatibility in mind — rewrite stored data or keep a compatible name.","Log the embedded class name from the exception message; it tells you exactly which jar is missing."],"tags":["serialization","classnotfound","classpath","rpc","hadoop-common"],"backgroundTag":"classnotfoundexception","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}