{"record":{"id":"87fc5306691d307e","repo":"apache/hadoop","slug":"invalid-header-on-split-file","errorCode":null,"errorMessage":"Invalid header on split file","messagePattern":"Invalid header on split file","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/split/SplitMetaInfoReader.java","lineNumber":60,"sourceCode":"public class SplitMetaInfoReader {\n  \n  public static JobSplit.TaskSplitMetaInfo[] readSplitMetaInfo(\n      JobID jobId, FileSystem fs, Configuration conf, Path jobSubmitDir) \n  throws IOException {\n    long maxMetaInfoSize = conf.getLong(MRJobConfig.SPLIT_METAINFO_MAXSIZE,\n        MRJobConfig.DEFAULT_SPLIT_METAINFO_MAXSIZE);\n    Path metaSplitFile = JobSubmissionFiles.getJobSplitMetaFile(jobSubmitDir);\n    String jobSplitFile = JobSubmissionFiles.getJobSplitFile(jobSubmitDir).toString();\n    FileStatus fStatus = fs.getFileStatus(metaSplitFile);\n    if (maxMetaInfoSize > 0 && fStatus.getLen() > maxMetaInfoSize) {\n      throw new IOException(\"Split metadata size exceeded \" +\n          maxMetaInfoSize +\". Aborting job \" + jobId);\n    }\n    FSDataInputStream in = fs.open(metaSplitFile);\n    byte[] header = new byte[JobSplit.META_SPLIT_FILE_HEADER.length];\n    in.readFully(header);\n    if (!Arrays.equals(JobSplit.META_SPLIT_FILE_HEADER, header)) {\n      throw new IOException(\"Invalid header on split file\");\n    }\n    int vers = WritableUtils.readVInt(in);\n    if (vers != JobSplit.META_SPLIT_VERSION) {\n      in.close();\n      throw new IOException(\"Unsupported split version \" + vers);\n    }\n    int numSplits = WritableUtils.readVInt(in); //TODO: check for insane values\n    JobSplit.TaskSplitMetaInfo[] allSplitMetaInfo = \n      new JobSplit.TaskSplitMetaInfo[numSplits];\n    for (int i = 0; i < numSplits; i++) {\n      JobSplit.SplitMetaInfo splitMetaInfo = new JobSplit.SplitMetaInfo();\n      splitMetaInfo.readFields(in);\n      JobSplit.TaskSplitIndex splitIndex = new JobSplit.TaskSplitIndex(\n          jobSplitFile, \n          splitMetaInfo.getStartOffset());\n      allSplitMetaInfo[i] = new JobSplit.TaskSplitMetaInfo(splitIndex, \n          splitMetaInfo.getLocations(), \n          splitMetaInfo.getInputDataLength());","sourceCodeStart":42,"sourceCodeEnd":78,"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/split/SplitMetaInfoReader.java#L42-L78","documentation":"readSplitMetaInfo requires the first bytes of job.splitmetainfo to equal JobSplit.META_SPLIT_FILE_HEADER; a mismatch throws before anything else is read. It means the file is truncated, corrupted, or not a split metadata file at all.","triggerScenarios":"A half-written job.splitmetainfo from an interrupted job submission; two jobs sharing one staging directory and overwriting each other's files; disk or NameNode corruption; jobSubmitDir pointing at a directory that never held a real submission.","commonSituations":"Resubmitting into a reused staging dir after a crashed client; scripts that rsync or copy partial submit dirs; NN/disk faults on the staging area; hand-crafted job submit dirs used with the AM.","solutions":["Resubmit the job into a fresh staging directory and let submission complete cleanly","Give each job a unique staging dir (mapreduce.job.staging-dir per user is the default; avoid sharing across concurrent jobs)","If corruption recurs, check NameNode and local disk health for the staging area"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"FileStatus st = fs.getFileStatus(JobSubmissionFiles.getJobSplitMetaFile(submitDir));\nif (st.getLen() < JobSplit.META_SPLIT_FILE_HEADER.length) {\n  throw new IOException(\"Truncated split metainfo at \" + submitDir);\n}","typeGuard":null,"tryCatchPattern":"try {\n  job.submit();\n} catch (IOException e) {\n  if (String.valueOf(e.getMessage()).contains(\"Invalid header\")) {\n    cleanStagingDir(stagingDir); // wipe and resubmit once\n    job.submit();\n  } else { throw e; }\n}","preventionTips":["Use a unique staging dir per job submission; never share across concurrent jobs","Treat interrupted submissions as poisoned: clean before resubmitting","Monitor NN/disk health of the staging area"],"tags":["mapreduce","job-submission","splits","corruption","staging"],"backgroundTag":"corrupt-file-header","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}