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
- Read the bracketed cause in the message — it names the actual HDFS IOException (lease, datanode, safe mode)
- Restore HDFS health; verify at least 2-3 live datanodes when using allow-append=true
- Consider allow-append=false so the sink writes a new suffixed file each roll instead of appending
- 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
- Keep HDFS healthy around roll boundaries — schedule NameNode maintenance away from interval starts
- Use allow-append=false when cluster health is marginal; new-file mode avoids lease/append pitfalls
- Alert on 'Failed to create new log file' / 'Failed flushing the stream' — they precede data loss
- Consider ignore-error=true only as an explicit degradation tradeoff
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
- Failed to create ${basePath}[source=${source}, allow-append=
- Error connecting to file system: ${basePath} [${ex}]
- Error logging in securely: [${ex}]
- Unrecognized flush interval: ${rollInterval}. Must be a numb
- Unrecognized unit for flush interval: ${flushUnit}. Must be
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/6ba05647cb1cb23e.
Report an issue: GitHub.