apache/iceberg · warning
Unable to load metrics class: '{}', falling back to null met
Error message
Unable to load metrics class: '{}', falling back to null metrics What it means
ADLSFileIO.initMetrics() reflectively constructs the ADLS metrics context class at initialize(). If the class is missing (NoClassDefFoundError), has no matching constructor, or doesn't implement MetricsContext, it warns and falls back to null metrics — the FileIO still works, just without metrics instrumentation.
Source
Thrown at azure/src/main/java/org/apache/iceberg/azure/adlsv2/ADLSFileIO.java:188
initMetrics(properties);
this.azureProperties
.vendedAdlsCredentialProvider()
.ifPresent(provider -> this.vendedAdlsCredentialProvider = provider);
}
@SuppressWarnings("CatchBlockLogException")
private void initMetrics(Map<String, String> props) {
// Report Hadoop metrics if Hadoop is available
try {
DynConstructors.Ctor<MetricsContext> ctor =
DynConstructors.builder(MetricsContext.class)
.hiddenImpl(DEFAULT_METRICS_IMPL, String.class)
.buildChecked();
MetricsContext context = ctor.newInstance("adls");
context.initialize(props);
this.metrics = context;
} catch (NoClassDefFoundError | NoSuchMethodException | ClassCastException e) {
LOG.warn(
"Unable to load metrics class: '{}', falling back to null metrics", DEFAULT_METRICS_IMPL);
}
}
@Override
public void deleteFiles(Iterable<String> pathsToDelete) throws BulkDeletionFailureException {
// Azure batch operations are not supported in all cases, e.g. with a user
// delegation SAS token, so avoid using it for now
AtomicInteger failureCount = new AtomicInteger();
Tasks.foreach(pathsToDelete)
.executeWith(ThreadPools.getWorkerPool())
.noRetry()
.suppressFailureWhenFinished()
.onFailure(
(file, exc) -> {
failureCount.incrementAndGet();
LOG.warn("Failed to delete file {}", file, exc);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Add the module providing the default metrics implementation to the classpath
- Check for dependency shading/conflicts that drop the metrics classes
- Align library versions so the constructor signature matches what ADLSFileIO expects
- If metrics are intentionally unwanted, ignore the warning
Example fix
// before (gradle) implementation 'org.apache.iceberg:iceberg-azure' // after implementation 'org.apache.iceberg:iceberg-azure' implementation 'org.apache.iceberg:iceberg-azure-bundle' // pulls metrics impl
Defensive patterns
Strategy: fallback
Validate before calling
try {
Class.forName("org.apache.iceberg.metrics.LoggingMetricsContext");
} catch (ClassNotFoundException e) {
LOG.warn("ADLS metrics impl missing from classpath; add iceberg-azure-bundle");
} Prevention
- Ship the bundle/jar containing the metrics implementation with the app
- Verify shaded jars retain the metrics classes
- Accept the null-metrics fallback only when instrumentation is intentionally disabled
When it happens
Trigger: Initializing ADLSFileIO without the metrics implementation on the classpath (e.g. the module providing DEFAULT_METRICS_IMPL is excluded), or with an incompatible version whose constructor signature changed.
Common situations: Shaded/minimal deployments missing the metrics module; dependency conflicts after upgrades; custom classpaths in Spark/Flink distributions.
Related errors
- Cannot load class %s, it does not exist in the classpath
- Cannot load class %s, it does not exist in the classpath
- Cannot initialize S3FileIOAwsClientFactory, missing no-arg c
- Cannot initialize AdlsTokenCredentialProvider, missing no-ar
- Cannot initialize AdlsTokenCredentialProvider, %s does not i
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/94f249eeaef558d0.
Report an issue: GitHub.