apache/kafka · error · IllegalStateException

Not a measurable: {metricValueProviderClass}

Error message

Not a measurable: {metricValueProviderClass}

What it means

Thrown by KafkaMetric.measurable() when the underlying metricValueProvider does not implement the Measurable interface. Kafka metrics are backed either by a Measurable (a synchronous function of config+time, e.g. Avg/Max/Rate) or by a Gauge-style MetricValueProvider whose value is supplied on demand. measurable() is only valid for the former; callers that need a numeric snapshot of either kind should use measurableValue(timeMs) or metricValue() instead.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/metrics/KafkaMetric.java:104

    /**
     * The method determines if the metric value provider is of type Measurable.
     *
     * @return true if the metric value provider is of type Measurable, false otherwise.
     */
    public boolean isMeasurable() {
        return this.metricValueProvider instanceof Measurable;
    }

    /**
     * Get the underlying metric provider, which should be a {@link Measurable}
     * @return Return the metric provider
     * @throws IllegalStateException if the underlying metric is not a {@link Measurable}.
     */
    public Measurable measurable() {
        if (isMeasurable())
            return (Measurable) metricValueProvider;
        else
            throw new IllegalStateException("Not a measurable: " + this.metricValueProvider.getClass());
    }

    /**
     * Take the metric and return the value, where the underlying metric provider should be a {@link Measurable}
     * @param timeMs The time that this metric is taken
     * @return Return the metric value if it's measurable, otherwise 0
     */
    double measurableValue(long timeMs) {
        synchronized (this.lock) {
            if (isMeasurable())
                return ((Measurable) metricValueProvider).measure(config, timeMs);
            else
                return 0;
        }
    }

    /**
     * Set the metric config.

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Guard the call: if (kafkaMetric.isMeasurable()) kafkaMetric.measurable(); else ... handle the gauge path.
  2. Prefer kafkaMetric.measurableValue(timeMs) which returns 0 for non-measurable metrics, or metricValue() for the provider's current value.
  3. If your custom provider should be measurable, implement org.apache.kafka.common.metrics.Measurable rather than just MetricValueProvider.

Example fix

// before: Measurable m = kafkaMetric.measurable();
// after:
if (kafkaMetric.isMeasurable()) {
    Measurable m = kafkaMetric.measurable();
} else {
    double v = kafkaMetric.measurableValue(System.currentTimeMillis());
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard with the public isMeasurable() check before calling measurable().
if (kafkaMetric.isMeasurable()) {
    Measurable m = kafkaMetric.measurable();
    double v = m.measure(config, System.currentTimeMillis());
} else {
    // provider is a non-Measurable MetricValueProvider (e.g., gauge); use value() instead.
}

Type guard

// Narrow to Measurable before invoking measurable().
if (!(metricValueProvider instanceof Measurable)) {
    // cannot call measurable(); use measurableValue() which returns 0 for non-measurables.
}
boolean isMeasurable(KafkaMetric km) { return km != null && km.isMeasurable(); }

Try / catch

try {
    Measurable m = kafkaMetric.measurable();
} catch (IllegalStateException e) {
    // provider is not Measurable; fall back to measurableValue(timeMs) or skip.
}

Prevention

When it happens

Trigger: Code holds a KafkaMetric reference and calls measurable() on one whose provider was registered via Metrics.addMetric(name, (MetricValueProvider<?>) gaugeLikeProvider). Because the provider is not Measurable, KafkaMetric.measurable() at line 104 throws IllegalStateException naming the actual provider class.

Common situations: Custom MetricValueProvider implementations (Gauges wrapping external state) being inspected by tooling that assumes every metric is measurable. Reporters or tests iterating over Metrics.metrics().values() and calling measurable() without first checking isMeasurable(). Version upgrades where a metric previously implemented Measurable and was refactored to a generic provider.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/f3c37dd2e2843da0.json. Report an issue: GitHub.