apache/hadoop · error · BadRequestException

tasktype must be either m or r

Error message

tasktype must be either m or r

What it means

getJobTasks maps the optional 'type' query parameter through MRApps.taskType(), which accepts exactly 'm' or 'r' (lowercase, MRApps.java:154-159). Any other non-empty value throws YarnRuntimeException inside, rethrown as a JAX-RS BadRequestException - HTTP 400 'tasktype must be either m or r'.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebServices.java:358

  @GET
  @Path("/jobs/{jobid}/tasks")
  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
  public TasksInfo getJobTasks(@Context HttpServletRequest hsr,
      @PathParam("jobid") String jid, @QueryParam("type") String type) {

    init();
    Job job = getJobFromJobIdString(jid, appCtx);
    checkAccess(job, hsr);
    TasksInfo allTasks = new TasksInfo();
    for (Task task : job.getTasks().values()) {
      TaskType ttype = null;
      if (type != null && !type.isEmpty()) {
        try {
          ttype = MRApps.taskType(type);
        } catch (YarnRuntimeException e) {
          throw new BadRequestException("tasktype must be either m or r");
        }
      }
      if (ttype != null && task.getType() != ttype) {
        continue;
      }
      allTasks.add(new TaskInfo(task));
    }
    return allTasks;
  }

  @GET
  @Path("/jobs/{jobid}/tasks/{taskid}")
  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
  public TaskInfo getJobTask(@Context HttpServletRequest hsr,
      @PathParam("jobid") String jid, @PathParam("taskid") String tid) {

    init();

View on GitHub (pinned to 2add963021)

Solutions

  1. Use type=m for map tasks and type=r for reduce tasks
  2. Omit the parameter entirely to list all tasks
  3. Normalize external input to a lowercase single letter before calling

Example fix

// before
GET /ws/v1/mapreduce/jobs/job_1_0001/tasks?type=map
// 400 { "tasktype must be either m or r" }

// after
GET /ws/v1/mapreduce/jobs/job_1_0001/tasks?type=m
Defensive patterns

Strategy: validation

Validate before calling

Set<String> VALID = Set.of("m", "r");
if (type != null && !VALID.contains(type)) {
  throw new IllegalArgumentException("type must be 'm' or 'r'");
}
// then: .queryParam("type", type)

Type guard

static boolean isValidTaskTypeFilter(String type) {
  return type == null || type.equals("m") || type.equals("r");
}

Try / catch

try {
  return listTasks(jid, type);
} catch (javax.ws.rs.BadRequestException bre) {
  if (bre.getMessage().contains("tasktype")) {
    return listTasks(jid, null); // retry without the filter
  }
  throw bre;
}

Prevention

When it happens

Trigger: GET /ws/v1/mapreduce/jobs/{jobid}/tasks?type=map, ?type=REDUCE, ?type=maps - any value other than 'm' or 'r'. Omitting 'type' (or sending an empty value) is valid and returns all tasks.

Common situations: Clients reuse human-readable words ('map', 'reduce') from the UI or old JobConf vocabulary instead of the REST symbols; uppercase input; trailing whitespace or encoding artifacts.

Related errors


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