{"record":{"id":"2f07d7e19b5a5ad6","repo":"apache/hadoop","slug":"only-killed-is-allowed-as-a-target-state","errorCode":null,"errorMessage":"Only 'KILLED' is allowed as a target state.","messagePattern":"Only 'KILLED' is allowed as a target state\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebServices.java","lineNumber":487,"sourceCode":"    init();\n    Job job = getJobFromJobIdString(jid, appCtx);\n    checkAccess(job, hsr);\n\n    String remoteUser = hsr.getRemoteUser();\n    UserGroupInformation callerUGI = null;\n    if (remoteUser != null) {\n      callerUGI = UserGroupInformation.createRemoteUser(remoteUser);\n    }\n\n    Task task = getTaskFromTaskIdString(tid, job);\n    TaskAttempt ta = getTaskAttemptFromTaskAttemptString(attId, task);\n    if (!ta.getState().toString().equals(targetState.getState())) {\n      // user is attempting to change state. right we only\n      // allow users to kill the job task attempt\n      if (targetState.getState().equals(TaskAttemptState.KILLED.toString())) {\n        return killJobTaskAttempt(ta, callerUGI, hsr);\n      }\n      throw new BadRequestException(\"Only '\"\n          + TaskAttemptState.KILLED.toString()\n          + \"' is allowed as a target state.\");\n    }\n\n    JobTaskAttemptState ret = new JobTaskAttemptState();\n    ret.setState(ta.getState().toString());\n\n    return Response.status(Status.OK).entity(ret).build();\n  }\n\n  @GET\n  @Path(\"/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}/counters\")\n  @Produces({ MediaType.APPLICATION_JSON + \"; \" + JettyUtils.UTF_8,\n      MediaType.APPLICATION_XML + \"; \" + JettyUtils.UTF_8 })\n  public JobTaskAttemptCounterInfo getJobTaskAttemptIdCounters(\n      @Context HttpServletRequest hsr, @PathParam(\"jobid\") String jid,\n      @PathParam(\"taskid\") String tid, @PathParam(\"attemptid\") String attId) {\n","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebServices.java#L469-L505","documentation":"The only state change the AM REST task-attempt endpoint implements is kill. If the requested state differs from the attempt's current state and is not KILLED, AMWebServices throws BadRequestException - HTTP 400 with \"Only 'KILLED' is allowed as a target state.\". A PUT whose target equals the current state succeeds as a no-op.","triggerScenarios":"PUT /ws/v1/mapreduce/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}/state with body {\"state\":\"SUCCEEDED\"} (or FAILED, RUNNING, ...) while the attempt is in a different state.","commonSituations":"Clients try to drive attempt lifecycle (rerun, force-fail, succeed) through the REST API; automation ported from MRv1 control interfaces assumes a full state machine that the API does not expose.","solutions":["Send {\"state\":\"KILLED\"} - the only supported target","GET .../attempts/{attemptid} first and skip the PUT when the state already matches","For broader control use the job-level kill: PUT /ws/v1/mapreduce/jobs/{jobid}/state with {\"state\":\"KILLED\"}"],"exampleFix":"// before\nPUT .../tasks/task_1_0001_m_000005/attempts/attempt_1_0001_m_000005_0/state\n{ \"state\": \"SUCCEEDED\" }\n// 400 { \"Only 'KILLED' is allowed as a target state.\" }\n\n// after\n{ \"state\": \"KILLED\" }","handlingStrategy":"validation","validationCode":"if (!\"KILLED\".equals(requestedState)\n    && !requestedState.equals(currentAttemptState)) {\n  throw new IllegalArgumentException(\n      \"Only KILLED is a supported target state via the AM REST API\");\n}","typeGuard":"static boolean isSupportedAttemptStateChange(String target, String current) {\n  return target.equals(current) || \"KILLED\".equals(target);\n}","tryCatchPattern":"try {\n  return putAttemptState(jid, tid, attId, target);\n} catch (javax.ws.rs.BadRequestException bre) {\n  // only KILLED is allowed; surface to the caller instead of retrying other states\n  throw new UnsupportedOperationException(\"attempt state changes limited to KILLED\", bre);\n}","preventionTips":["Hard-code KILLED as the only target in automation scripts","Read the current state first and skip no-op PUTs","Do not port MRv1 lifecycle control logic to this endpoint - it supports kill only"],"tags":["mapreduce","rest","http-400","state-transition","task-attempt"],"backgroundTag":"invalid-state-transition","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}