apache/hadoop · error · MetricsException

Unsupported gauge type: {}

Error message

Unsupported gauge type: {}

What it means

MethodMetric.newGauge builds the implementation for an @Metric-annotated method with type GAUGE; supported return types are int/Integer, long/Long, float/Float, and double/Double (everything else in the supported chain falls back to Double). Any other type — String, boolean, BigDecimal — falls through to MetricsException('Unsupported gauge type: <class name>').

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MethodMetric.java:122

  }

  MutableMetric newGauge(final Class<?> t) {
    if (isInt(t) || isLong(t) || isFloat(t) || isDouble(t)) {
      return new MutableMetric() {
        @Override public void snapshot(MetricsRecordBuilder rb, boolean all) {
          try {
            Object ret = method.invoke(obj, (Object[]) null);
            if (isInt(t)) rb.addGauge(info, ((Integer) ret).intValue());
            else if (isLong(t)) rb.addGauge(info, ((Long) ret).longValue());
            else if (isFloat(t)) rb.addGauge(info, ((Float) ret).floatValue());
            else rb.addGauge(info, ((Double) ret).doubleValue());
          } catch (Exception ex) {
            LOG.error("Error invoking method "+ method.getName(), ex);
          }
        }
      };
    }
    throw new MetricsException("Unsupported gauge type: "+ t.getName());
  }

  MutableMetric newTag(Class<?> resType) {
    if (resType == String.class) {
      return new MutableMetric() {
        @Override public void snapshot(MetricsRecordBuilder rb, boolean all) {
          try {
            Object ret = method.invoke(obj, (Object[]) null);
            rb.tag(info, (String) ret);
          } catch (Exception ex) {
            LOG.error("Error invoking method "+ method.getName(), ex);
          }
        }
      };
    }
    throw new MetricsException("Unsupported tag type: "+ resType.getName());
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Change the method's return type to one of int, long, float, double
  2. For boolean/string values, expose them as tags (String-returning method) instead of gauges
  3. Convert the value inside the method (e.g., return bigDecimal.doubleValue())

Example fix

// before
@Metric
public String queueSizeLabel() { return labels.get("q1"); }

// after
@Metric
public long queueSize() { return sizes.get("q1"); }
Defensive patterns

Strategy: type-guard

Validate before calling

for (Method m : cls.getDeclaredMethods()) {
  Metric ann = m.getAnnotation(Metric.class);
  if (ann != null && !isGaugeType(m.getReturnType())) {
    throw new IllegalStateException("@Metric gauge on unsupported type: " + m);
  }
}

Type guard

static boolean isGaugeType(Class<?> t) {
  return t == int.class || t == Integer.class
      || t == long.class || t == Long.class
      || t == float.class || t == Float.class
      || t == double.class || t == Double.class;
}

Prevention

When it happens

Trigger: @Metric (default type GAUGE, or Type.GAUGE) on a method returning String, boolean, java.math.BigDecimal, or any non-numeric type.

Common situations: Annotating convenience getters (String labels, boolean flags) as gauges; BigDecimal/Number subclasses from domain code used directly as metric methods.

Related errors


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