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
- Use type=m for map tasks and type=r for reduce tasks
- Omit the parameter entirely to list all tasks
- 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
- Whitelist 'm' and 'r' at the client boundary; reject anything else before the request
- Lowercase external input before using it as the filter
- Omit the parameter to get all tasks when the caller's intent is unclear
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
- tasktype must be either m or r
- Only 'KILLED' is allowed as a target state.
- missing task-type.
- missing attempt-state.
- Bad Request: Missing job ID
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/3a17148d679c50f7.
Report an issue: GitHub.