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

GCSFileIO.initMetrics attempts to reflectively instantiate the default GCS metrics implementation class. If that class cannot be loaded/constructed (missing dependency, wrong signature, or ClassCastException), the FileIO logs a warning and falls back to null metrics — the catalog still works but GCS request metrics are not collected.

Source

Thrown at gcp/src/main/java/org/apache/iceberg/gcp/gcs/GCSFileIO.java:181

  @Override
  public void initialize(Map<String, String> props) {
    this.properties = SerializableMap.copyOf(props);
    initMetrics(properties);
  }

  @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("gcs");
      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);
    }
  }

  private Map<String, PrefixedStorage> storageByPrefix() {
    if (null == storageByPrefix) {
      synchronized (this) {
        if (null == storageByPrefix) {
          Map<String, PrefixedStorage> localStorageByPrefix = Maps.newHashMap();

          localStorageByPrefix.put(
              ROOT_STORAGE_PREFIX,
              new PrefixedStorage(ROOT_STORAGE_PREFIX, properties, storageSupplier));
          storageCredentials.stream()
              .filter(c -> c.prefix().startsWith(ROOT_STORAGE_PREFIX))
              .collect(Collectors.toList())
              .forEach(
                  storageCredential -> {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Add the GCS metrics dependency (org.apache.iceberg:iceberg-gcp-bundle or the module providing the metrics impl) to the classpath
  2. Check the class named by DEFAULT_METRICS_IMPL exists with the expected (String) constructor
  3. If metrics are not needed, ignore the warning — behavior is otherwise unaffected
  4. Align Iceberg versions so iceberg-gcp and the metrics module match

Example fix

// before (Maven)
<dependency>org.apache.iceberg:iceberg-gcp</dependency>
// after
<dependency>org.apache.iceberg:iceberg-gcp</dependency>
<dependency>org.apache.iceberg:iceberg-gcp-bundle</dependency> <!-- provides metrics impl -->
Defensive patterns

Strategy: fallback

Validate before calling

try { Class.forName("org.apache.iceberg.gcp.gcs.GcsMetricsContext"); } catch (ClassNotFoundException e) { /* add metrics dep */ }

Prevention

When it happens

Trigger: Calling GCSFileIO.initialize(...) when the metrics class (gcs-metrics module, e.g. showcasing opencensus/opentelemetry deps) is not on the classpath, its constructor signature changed, or it does not implement MetricsContext.

Common situations: Using iceberg-gcp without the gcp-bundle/shaded jar; depending only on iceberg-gcp core and missing the optional metrics dependency; upgrading Iceberg where DEFAULT_METRICS_IMPL class moved.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/e2a7731f4d1b51b9. Report an issue: GitHub.