{"record":{"id":"fc8d8a1cd9e693c4","repo":"apache/hadoop","slug":"user-is-not-set-in-the-application-report","errorCode":null,"errorMessage":"User is not set in the application report","messagePattern":"User is not set in the application report","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ClientServiceDelegate.java","lineNumber":255,"sourceCode":"          LOG.info(\"Could not get Job info from RM for job \" + jobId\n              + \". Redirecting to job history server.\");\n          return checkAndGetHSProxy(null, JobState.RUNNING);\n        }\n      } catch (InterruptedException e) {\n        LOG.warn(\"getProxy() call interrupted\", e);\n        throw new YarnRuntimeException(e);\n      } catch (YarnException e) {\n        throw new IOException(e);\n      }\n    }\n\n    /** we just want to return if its allocating, so that we don't\n     * block on it. This is to be able to return job status\n     * on an allocating Application.\n     */\n    String user = application.getUser();\n    if (user == null) {\n      throw new IOException(\"User is not set in the application report\");\n    }\n    if (application.getYarnApplicationState() == YarnApplicationState.NEW\n        || application.getYarnApplicationState() ==\n            YarnApplicationState.NEW_SAVING\n        || application.getYarnApplicationState() == YarnApplicationState.SUBMITTED\n        || application.getYarnApplicationState() == YarnApplicationState.ACCEPTED) {\n      realProxy = null;\n      return getNotRunningJob(application, JobState.NEW);\n    }\n\n    if (application.getYarnApplicationState() == YarnApplicationState.FAILED) {\n      realProxy = null;\n      return getNotRunningJob(application, JobState.FAILED);\n    }\n\n    if (application.getYarnApplicationState() == YarnApplicationState.KILLED) {\n      realProxy = null;\n      return getNotRunningJob(application, JobState.KILLED);","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ClientServiceDelegate.java#L237-L273","documentation":"Thrown by ClientServiceDelegate while rebuilding a proxy for a running/finished application: the ApplicationReport fetched from the ResourceManager has a null user field. The job client requires the user (for proxy UGI, token ownership, and log paths) and fails fast with IOException instead of proceeding with incomplete identity. It usually indicates an inconsistent or partial report from the RM rather than a client bug.","triggerScenarios":"ClusterClient/getJobStatus on a job whose ApplicationReport.getUser() returns null — seen when the RM returns a report for an application in an early/aborted state or from an RM version/upgrade mismatch where the field is unset. The check runs right after the report is obtained in the proxy-rebuild path, before the NEW/ACCEPTED state shortcuts.","commonSituations":"Querying job status during RM restart/failover while app state is being replayed; Version skew between job client and ResourceManager (older MR client against newer RM field semantics); Applications submitted through a non-standard client that did not set the submitter before RM persistence","solutions":["Retry the status call after a short delay — reports during RM transitions are often transiently incomplete","Align client and cluster Hadoop versions (same hadoop-mapreduce-client-* artifacts)","If persistent, inspect the application via yarn application -status <appId> to confirm the RM itself reports a user; if absent, the submission side is broken (fix the submitting client/job context user)"],"exampleFix":"// before\nJobStatus s = jobClient.getJobStatus(jobId); // throws IOException: user null\n\n// after\nJobStatus s = retryWithBackoff(() -> jobClient.getJobStatus(jobId),\n    /*attempts*/ 5, /*delayMs*/ 2000);\n// transient RM reports resolve after failover completes; if not,\n// check `yarn application -status` for the missing user field","handlingStrategy":"try-catch","validationCode":"// pre-check the report the same way the delegate does\nApplicationReport rpt = yarnClient.getApplicationReport(appId);\nif (rpt.getUser() == null)\n  throw new IllegalStateException(\"RM returned incomplete report; retry shortly\");","typeGuard":null,"tryCatchPattern":"try {\n  status = cluster.getJobStatus(jobId);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"User is not set in the application report\")) {\n    Thread.sleep(2000); status = cluster.getJobStatus(jobId); // transient RM state\n  } else throw e;\n}","preventionTips":["Retry status polls during RM restart/failover windows — reports are transiently incomplete","Pin client artifacts to the cluster's Hadoop version to avoid field-semantics skew","Validate submission code sets the user (JobConf user / UGI) before submit"],"tags":["hadoop","mapreduce","yarn","application-report","null-field","client"],"backgroundTag":"missing-required-field","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}