apache/hadoop · error · IOException

User is null while setting up jobhistory eventwriter

Error message

User is null while setting up jobhistory eventwriter

What it means

setupEventWriter resolves the job's owner with UserGroupInformation.getCurrentUser().getShortUserName() and refuses to create the history event writer when that returns null. A null short user name means the UGI subject carries no usable principal (empty or malformed user string), so the AM cannot attribute ownership to the history files and aborts.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/jobhistory/JobHistoryEventHandler.java:532

   * @throws IOException
   */
  protected void setupEventWriter(JobId jobId, AMStartedEvent amStartedEvent)
      throws IOException {
    if (stagingDirPath == null) {
      LOG.error("Log Directory is null, returning");
      throw new IOException("Missing Log Directory for History");
    }

    MetaInfo oldFi = fileMap.get(jobId);
    Configuration conf = getConfig();

    // TODO Ideally this should be written out to the job dir
    // (.staging/jobid/files - RecoveryService will need to be patched)
    Path historyFile = JobHistoryUtils.getStagingJobHistoryFile(
        stagingDirPath, jobId, startCount);
    String user = UserGroupInformation.getCurrentUser().getShortUserName();
    if (user == null) {
      throw new IOException(
          "User is null while setting up jobhistory eventwriter");
    }

    String jobName = context.getJob(jobId).getName();
    EventWriter writer = (oldFi == null) ? null : oldFi.writer;
 
    Path logDirConfPath =
        JobHistoryUtils.getStagingConfFile(stagingDirPath, jobId, startCount);
    if (writer == null) {
      try {
        writer = createEventWriter(historyFile);
        LOG.info("Event Writer setup for JobId: " + jobId + ", File: "
            + historyFile);
      } catch (IOException ioe) {
        LOG.info("Could not create log file: [" + historyFile + "] + for job "
            + "[" + jobName + "]");
        throw ioe;
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Check which OS/JVM user the AM container runs as and that UserGroupInformation.getCurrentUser().getShortUserName() returns a name (test with 'hadoop kerbname' or a small UGI dump)
  2. Set a valid HADOOP_USER_NAME for simple auth, or fix the Kerberos principal/user mapping (hadoop.security.auth_to_local) so login produces a real short name
  3. If the error appears only under a custom doAs, unwrap the Subject before history setup or use UserGroupInformation.createRemoteUser with a concrete name
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check identity before launching jobs/AMs under custom subjects
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
String user = ugi.getShortUserName();
if (user == null || user.isEmpty()) {
  throw new IllegalStateException("No resolvable short user name for " + ugi);
}

Prevention

When it happens

Trigger: AM executes inside a Subject whose principal yields no short name (broken doAs); simple-auth environment producing a blank user (bad HADOOP_USER_NAME); Kerberos login with a principal the JVM cannot parse into a short name.

Common situations: Custom UGI.doAs wrappers around job submission or AM code; SPNEGO/Kerberos misconfiguration (missing realm mapping); containers launched with corrupted user environment after NM changes; edge cases after Hadoop security upgrades.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/d9681506bb94bcf4. Report an issue: GitHub.