apache/hadoop · error · MetricsException
Unexpected metrics type {} for {}
Error message
Unexpected metrics type {} for {} What it means
MetricsRegistry.newRate(name, desc, extended, returnExisting=true) is the get-or-create path for rate metrics: an existing registration under that name is returned only if it is a MutableRate. If the name maps to a different MutableMetric subclass (counter, gauge, quantiles), it throws MetricsException('Unexpected metrics type <class> for <name>').
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MetricsRegistry.java:321
/**
* Create a mutable rate metric (for throughput measurement).
* @param name of the metric
* @param desc description
* @param extended produce extended stat (stdev/min/max etc.) if true
* @return a new mutable rate metric object
*/
public MutableRate newRate(String name, String desc, boolean extended) {
return newRate(name, desc, extended, true);
}
@InterfaceAudience.Private
public synchronized MutableRate newRate(String name, String desc,
boolean extended, boolean returnExisting) {
if (returnExisting) {
MutableMetric rate = metricsMap.get(name);
if (rate != null) {
if (rate instanceof MutableRate) return (MutableRate) rate;
throw new MetricsException("Unexpected metrics type "+ rate.getClass()
+" for "+ name);
}
}
checkMetricName(name);
MutableRate ret = new MutableRate(name, desc, extended);
metricsMap.put(name, ret);
return ret;
}
public synchronized MutableRatesWithAggregation newRatesWithAggregation(
String name) {
checkMetricName(name);
MutableRatesWithAggregation rates = new MutableRatesWithAggregation();
metricsMap.put(name, rates);
return rates;
}
public synchronized MutableRollingAverages newMutableRollingAverages(View on GitHub (pinned to 2add963021)
Solutions
- Rename one of the two metrics so each name has one type within the registry
- If a rate is intended, remove the earlier counter/gauge/quantiles registration of that name
- Audit the annotated class or registry for duplicate metric names and give them distinct names
Example fix
// before
registry.newCounter("ProcTime", "Processing time");
registry.newRate("ProcTime", "Processing time", true); // throws
// after
registry.newCounter("ProcTimeCount", "Processing count");
registry.newRate("ProcTime", "Processing time", true); Defensive patterns
Strategy: validation
Validate before calling
Map<String, Class<?>> registered = new ConcurrentHashMap<>();
// record every registration: registered.put("Foo", MutableRate.class);
Class<?> existing = registered.get("Foo");
if (existing == null || existing == MutableRate.class) {
registry.newRate("Foo", "desc", true);
} Try / catch
try {
registry.newRate("Foo", "desc", true);
} catch (MetricsException e) {
// "Unexpected metrics type" => name already claimed by a non-rate metric; rename
registry.newRate("FooRate", "desc", true);
} Prevention
- Keep one metric type per name within a registry — decide ownership up front
- Track registered names and their kinds in the component that owns the registry
- Grep annotated classes for duplicate @Metric names during code review
When it happens
Trigger: Calling newRate("Foo", ..., true) after newCounter/newGauge/newQuantiles already registered a non-rate metric named "Foo" in the same registry.
Common situations: Name collisions inside one @Metrics-annotated class or registry — e.g., a MutableStat field and an implicit newRate sharing a name; refactors that changed a metric's type while the old declaration stayed.
Related errors
- Unsupported add(value) for metric {}
- Unsupported counter type: {}
- Unsupported gauge type: {}
- Unsupported tag type: {}
- Metric name {} already exists!
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/ce77d96228f58c46.
Report an issue: GitHub.