apache/hadoop · error · IllegalArgumentException

JobId string : {} is not properly formed

Error message

JobId string : {} is not properly formed

What it means

JobID.forName(String) parses canonical MapReduce job identifiers of the exact shape job_<jtIdentifier>_<id> (split on '_', exactly 3 parts, first part 'job', last part parseable by Integer.parseInt). The source swallows parse exceptions and falls through to IllegalArgumentException('JobId string : <str> is not properly formed'). It is the standard entry point when converting job-id strings from logs, paths, or RPC payloads back to a JobID.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/JobID.java:156

  
  /** Construct a JobId object from given string 
   * @return constructed JobId object or null if the given String is null
   * @throws IllegalArgumentException if the given string is malformed
   */
  public static JobID forName(String str) throws IllegalArgumentException {
    if(str == null)
      return null;
    try {
      String[] parts = str.split("_");
      if(parts.length == 3) {
        if(parts[0].equals(JOB)) {
          return new org.apache.hadoop.mapred.JobID(parts[1], 
                                                    Integer.parseInt(parts[2]));
        }
      }
    }catch (Exception ex) {//fall below
    }
    throw new IllegalArgumentException("JobId string : " + str 
        + " is not properly formed");
  }
  
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Extract only the last path component if the id came from a directory name: new Path(str).getName()
  2. For attempt/task strings, parse the richer type first: TaskAttemptID.forName(s).getJobID() or TaskID.forName(s).getJobID()
  3. Pre-validate with a regex like ^job_[^_]+_\d+$ before calling forName
  4. Remember yarn application ids (application_123_456) are not JobIDs — convert via the app report or use ApplicationId instead

Example fix

// before
JobID id = JobID.forName("attempt_201304121800_0001_m_000003_0"); // 6 parts -> throws

// after
JobID id = TaskAttemptID.forName("attempt_201304121800_0001_m_000003_0").getJobID();
// or from a staging path:
JobID id2 = JobID.forName(new Path(stagingPath).getName());
Defensive patterns

Strategy: validation

Validate before calling

// strict pre-check before JobID.forName
private static final Pattern JOB_ID = Pattern.compile("^job_[^_/]+_\\d+$");

if (s == null || !JOB_ID.matcher(s).matches()) {
  throw new IllegalArgumentException("Not a canonical JobID (expected job_<jtId>_<num>): " + s);
}
JobID id = JobID.forName(s);

Type guard

static boolean isCanonicalJobId(String s) {
  return s != null && s.startsWith("job_") && s.split("_").length == 3;
}

// usage: if (isCanonicalJobId(token)) { JobID id = JobID.forName(token); }

Try / catch

try {
  JobID id = JobID.forName(raw.trim());
} catch (IllegalArgumentException e) {
  // message shape: 'JobId string : X is not properly formed'
  log.warn("Skipping non-job token {}", raw);
}

Prevention

When it happens

Trigger: Passing a TaskID/TaskAttemptID string (task_.../attempt_...) which has 5-6 parts; passing a full staging path like /tmp/hadoop-yarn/staging/user/.staging/job_..._0001 instead of the id alone; trailing whitespace/newline from shell output; a non-numeric sequence number; a null-adjacent typo like 'job_2013041218000033' (only 2 parts).

Common situations: Log scrapers and MR output-parsing scripts that feed raw directory names into forName; automation piping `yarn application -list` output (appid format application_..., which is NOT a JobID) into JobID.forName; ids copied with quotes or whitespace.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/3ae7d1451fcec9f0. Report an issue: GitHub.