apache/hadoop · error · IOException
Unknown Task {}
Error message
Unknown Task {} What it means
verifyAndGetTask throws this IOException when the parent job resolves but job.getTask(taskID) returns null — the TaskId is syntactically valid but no such task exists in this job. TaskIds embed their own job id and type/sequence, so cross-job or out-of-range ids land here after verifyAndGetJob already passed.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/client/MRClientService.java:223
Job job = appContext.getJob(jobID);
if (job == null && exceptionThrow) {
throw new IOException("Unknown Job " + jobID);
}
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
if (job != null && !job.checkAccess(ugi, accessType)) {
throw new AccessControlException("User " + ugi.getShortUserName()
+ " cannot perform operation " + accessType.name() + " on "
+ jobID);
}
return job;
}
private Task verifyAndGetTask(TaskId taskID,
JobACL accessType) throws IOException {
Task task =
verifyAndGetJob(taskID.getJobId(), accessType, true).getTask(taskID);
if (task == null) {
throw new IOException("Unknown Task " + taskID);
}
return task;
}
private TaskAttempt verifyAndGetAttempt(TaskAttemptId attemptID,
JobACL accessType) throws IOException {
TaskAttempt attempt = verifyAndGetTask(attemptID.getTaskId(),
accessType).getAttempt(attemptID);
if (attempt == null) {
throw new IOException("Unknown TaskAttempt " + attemptID);
}
return attempt;
}
@Override
public GetCountersResponse getCounters(GetCountersRequest request)
throws IOException {
JobId jobId = request.getJobId();View on GitHub (pinned to 2add963021)
Solutions
- Iterate job.getTasks().keySet() (or use job.getTask(id) on the handle from the same job) instead of constructing TaskIds by hand
- Refresh the Job handle after AM restart so embedded job attempt state matches
- Log the requested TaskId next to the AM's live task list when debugging
Defensive patterns
Strategy: validation
Validate before calling
// only ask for tasks that actually exist on the current handle
Job job = cluster.getJob(JobID.forName(jobIdString));
for (TaskReport report : job.getTaskReports(type)) { // enumerates real tasks
process(report.getTaskId());
} Prevention
- Never construct TaskIds arithmetically — enumerate them from TaskReports
- Bound task indices by the configured map/reduce counts if you must build ids
- Refresh the Job handle after AM restarts so embedded ids stay valid
When it happens
Trigger: Client builds a TaskId with a wrong task number or wrong embedded JobId; querying a task index beyond mapreduce.job.maps/reduces; task id cached from a prior run of the same job.
Common situations: Polling loops that increment task indices instead of using job.getTasks(); ids copied from logs of an earlier attempt; ater AM restart with task renumbering.
Related errors
- Unknown Job {}
- Unknown TaskAttempt {}
- taskid {} not found or invalid
- task not found with id {}
- missing task ID
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/90d701de72d6cc5f.
Report an issue: GitHub.