apache/hadoop · error · MetricsException

${message}: ${currentFilePath} [${t}]

Error message

${message}: ${currentFilePath} [${t}]

What it means

throwMetricsException(message, t) wraps a Throwable — practically always an IOException — caught while the sink operates on the current metrics file, and rethrows it as MetricsException with the message, current file path and cause string appended: "<message>: <currentFilePath> [<t>]". Its call sites in this sink are 'Failed to create new log file' (rolling to a new file), 'Failed flushing the stream' and 'Unable to flush log file' (hsync/hflush). It is suppressed entirely when ignore-error is true.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/sink/RollingFileSystemSink.java:926

      throw new MetricsException(message + ": " + currentFilePath);
    }
  }

  /**
   * If the sink isn't set to ignore errors, wrap the Throwable in a
   * {@link MetricsException} and throw it.  The message parameter will be used
   * as the new exception's message with the current file name
   * ({@link #currentFilePath}) and the Throwable's string representation
   * appended to it.
   *
   * @param message the exception message. The message will have a colon, the
   * current file name ({@link #currentFilePath}), and the Throwable's string
   * representation (wrapped in square brackets) appended to it.
   * @param t the Throwable to wrap
   */
  private void throwMetricsException(String message, Throwable t) {
    if (!ignoreError) {
      throw new MetricsException(message + ": " + currentFilePath + " ["
          + t.toString() + "]", t);
    }
  }

  /**
   * If the sink isn't set to ignore errors, throw a new
   * {@link MetricsException}.  The message parameter will be used  as the
   * new exception's message with the current file name
   * ({@link #currentFilePath}) appended to it.
   *
   * @param message the exception message. The message will have a colon and
   * the current file name ({@link #currentFilePath}) appended to it.
   */
  private void throwMetricsException(String message) {
    if (!ignoreError) {
      throw new MetricsException(message + ": " + currentFilePath);
    }
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Read the bracketed cause in the message — it names the actual HDFS IOException (lease, datanode, safe mode)
  2. Restore HDFS health; verify at least 2-3 live datanodes when using allow-append=true
  3. Consider allow-append=false so the sink writes a new suffixed file each roll instead of appending
  4. Set ignore-error=true to keep the daemon metrics pipeline alive at the cost of dropped data while diagnosing
Defensive patterns

Strategy: fallback

Validate before calling

// before enabling append mode, confirm HDFS supports it and has datanodes
if (allowAppend && !fileSystem.append(new Path(basePath, "probe")).isPresent()) {
  LOG.warn("Target filesystem may not support append; prefer allow-append=false");
}

Try / catch

try {
  sink.flush();
} catch (MetricsException e) {
  // '<message>: <file> [<cause>]' — the bracketed cause is the real HDFS IOException
  // fallback: log, keep daemon alive, rely on next roll opening a fresh file
  LOG.error("Metrics file flush failed ({}): {}", currentFilePath, e.getCause(), e);
}

Prevention

When it happens

Trigger: FileSystem.create/append failing at roll time (permissions, NameNode issues); hsync/hflush IOException from HDFS lease recovery or datanode failures; allow-append=true with fewer than the minimum live datanodes.

Common situations: The interval roll coinciding with HDFS maintenance or an unhealthy cluster; the current file's lease being stolen by another process; safe mode during a roll.

Related errors


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