apache/hadoop · error · IOException
Unknown TaskAttempt {}
Error message
Unknown TaskAttempt {} What it means
verifyAndGetAttempt throws this IOException when the parent task resolves but task.getAttempt(attemptID) returns null — the attempt number does not exist for that task (attempts are numbered 0..n-1 per task, bounded by mapreduce.map.maxattempts / mapreduce.reduce.maxattempts).
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:233
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();
Job job = verifyAndGetJob(jobId, JobACL.VIEW_JOB, true);
GetCountersResponse response =
recordFactory.newRecordInstance(GetCountersResponse.class);
response.setCounters(TypeConverter.toYarn(job.getAllCounters()));
return response;
}
@Override
public GetJobReportResponse getJobReport(GetJobReportRequest request)
throws IOException {View on GitHub (pinned to 2add963021)
Solutions
- Enumerate real attempts via task.getAttempts().keySet() rather than constructing TaskAttemptId with a guessed number
- Re-query the task report to learn which attempts exist before fetching attempt-level counters/diagnostics
- Treat 'Unknown TaskAttempt' as a transient miss during task churn and retry once after a report refresh
Defensive patterns
Strategy: validation
Validate before calling
// before attempt-level queries, learn which attempts exist
TaskReport report = ...; // from job.getTaskReports(type)
for (TaskAttemptID attemptId : report.getRunningTaskAttemptIds().isEmpty()
? completedAttemptIdsFromTaskReport(report)
: report.getRunningTaskAttemptIds()) {
queryAttempt(attemptId);
} Prevention
- Use TaskReport.getRunningTaskAttemptIds() / task.getAttempts() instead of guessing attempt numbers
- Treat attempt queries as eventually-consistent during speculative execution and re-check the report on miss
When it happens
Trigger: Client requests attemptId with attempt number >= attempts actually launched so far (race: asking about attempt 1 while only attempt 0 exists); attempt id string concatenated with a stale attempt counter; querying after the attempt was finalized.
Common situations: Progress dashboards computing attempt ids arithmetically instead of reading TaskReport.getCurrentAttemptAttemptIds / attempt lists; races between speculative-execution attempt launch and client queries.
Related errors
- Unknown Job {}
- Unknown Task {}
- Only 'KILLED' is allowed as a target state.
- too many failures downloading events
- Could not connect to History server.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/97a16a6cd4935c48.
Report an issue: GitHub.