{"record":{"id":"e94e4f097f4c0c49","repo":"apache/hadoop","slug":"failed-tuple-init","errorCode":null,"errorMessage":"Failed tuple init","messagePattern":"Failed tuple init","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/join/TupleWritable.java","lineNumber":207,"sourceCode":"    values = new Writable[card];\n    readBitSet(in, card, written);\n    Class<? extends Writable>[] cls = new Class[card];\n    try {\n      for (int i = 0; i < card; ++i) {\n        cls[i] = Class.forName(Text.readString(in)).asSubclass(Writable.class);\n      }\n      for (int i = 0; i < card; ++i) {\n        if (cls[i].equals(NullWritable.class)) {\n          values[i] = NullWritable.get();\n        } else {\n          values[i] = cls[i].newInstance();\n        }\n        if (has(i)) {\n          values[i].readFields(in);\n        }\n      }\n    } catch (ClassNotFoundException e) {\n      throw new IOException(\"Failed tuple init\", e);\n    } catch (IllegalAccessException e) {\n      throw new IOException(\"Failed tuple init\", e);\n    } catch (InstantiationException e) {\n      throw new IOException(\"Failed tuple init\", e);\n    }\n  }\n\n  /**\n   * Record that the tuple contains an element at the position provided.\n   */\n  void setWritten(int i) {\n    written.set(i);\n  }\n\n  /**\n   * Record that the tuple does not contain an element at the position\n   * provided.\n   */","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/join/TupleWritable.java#L189-L225","documentation":"TupleWritable serializes the class name of every element (TupleWritable.write, TupleWritable.java:174). On read, TupleWritable.readFields loads each class via Class.forName and rethrows failure as IOException('Failed tuple init', e) — this instance wraps ClassNotFoundException: an element class named in the stream could not be loaded on the reading JVM.","triggerScenarios":"A mapper/reducer reading join output (TupleWritable) where an element class (custom Writable) is missing from the task classpath: jar not shipped with the job (job.setJarByClass omitted / libjars missing), class renamed between write and read, shaded/relocated class names in the serialized stream, or classes written by a newer job version read by an older one.","commonSituations":"Custom Writable key/value classes in join data flows; 'hadoop jar' without -libjars; Oozie/Spark-generated data read by a MapReduce join with a different libset; class relocation by maven-shade-plugin changing binary names; client-side jar present but task-side classpath lacking the class.","solutions":["Ship the jar containing the element Writable class with the job: use -libjars on hadoop jar, job.setJarByClass(MyWritable.class), or place the jar in the job's lib directory / DistributedCache","Ensure the exact class name (package included) present at write time exists at read time — avoid renaming or relocating Writable classes across versions","For shaded deployments, keep serialized class names stable (exclude Writable packages from relocation) or use a stable wrapper Writable","Catch IOException around reader.next() and inspect getCause(): ClassNotFoundException names the missing class — then verify with 'hadoop classpath' / task logs which jar is absent"],"exampleFix":"# before\nhadoop jar myjoin.jar com.acme.JoinDriver /in /out   # custom Writable in acme-common.jar not shipped\n\n# after\nhadoop jar myjoin.jar com.acme.JoinDriver -libjars acme-common.jar /in /out\n\n// also in driver:\njob.setJarByClass(com.acme.common.MyTupleElement.class); // ensure task classpath contains it","handlingStrategy":"validation","validationCode":"static void requireTupleClassesOnClasspath(Path sampleData, Configuration conf) throws IOException {\n  // read one record locally and fail fast if any element class is missing\n  try (java.io.DataInputStream in = new java.io.DataInputStream(\n      sampleData.getFileSystem(conf).open(sampleData))) {\n    TupleWritable t = new TupleWritable(new Writable[0]);\n    t.readFields(in); // throws 'Failed tuple init' with ClassNotFoundException as cause if missing\n  } catch (IOException e) {\n    if (e.getCause() instanceof ClassNotFoundException)\n      throw new IllegalStateException(\"Missing class on classpath: \" + e.getCause().getMessage()\n        + \" — add its jar via -libjars / job.setJarByClass\", e);\n    throw e;\n  }\n}","typeGuard":null,"tryCatchPattern":"try { tuple.readFields(in); } catch (IOException e) { if (e.getCause() instanceof ClassNotFoundException) { /* log missing class name, fix classpath, fail task with actionable message */ } throw e; }","preventionTips":["Ship custom Writable jars with the job (-libjars, setJarByClass, lib/ dir in the job jar)","Never rename/relocate Writable classes whose names are serialized into data","Smoke-test reading one record in the driver before launching the full job"],"tags":["hadoop","mapreduce","join","classloader","serialization"],"backgroundTag":"classnotfound-serialization","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}