apache/seatunnel · error · SeaTunnelException
The value of Metric does not support ${metricType} data type
Error message
The value of Metric does not support ${metricType} data type What it means
SeaTunnelMetricsContext.provideDynamicMetrics converts SeaTunnel Metric values into Hazelcast/Micrometer probes. It handles Counter and Meter; any other Metric implementation hits the else branch and throws SeaTunnelException 'The value of Metric does not support <SimpleName> data type'. This happens while serving dynamic metrics for the cluster/web UI.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/metrics/SeaTunnelMetricsContext.java:56
public void provideDynamicMetrics(MetricDescriptor tagger, MetricsCollectionContext context) {
metrics.forEach(
(name, metric) -> {
if (metric instanceof Counter) {
context.collect(
tagger.copy(),
name,
ProbeLevel.INFO,
toProbeUnit(metric.unit()),
((Counter) metric).getCount());
} else if (metric instanceof Meter) {
context.collect(
tagger.copy(),
name,
ProbeLevel.INFO,
toProbeUnit(metric.unit()),
((Meter) metric).getRate());
} else {
throw new SeaTunnelException(
"The value of Metric does not support "
+ metric.getClass().getSimpleName()
+ " data type");
}
});
}
private ProbeUnit toProbeUnit(Unit unit) {
return ProbeUnit.valueOf(unit.name());
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Change the connector metric implementation to standard Counter or Meter from the engine API.
- Rebuild the connector against the same SeaTunnel API version as the engine to avoid class identity mismatches.
- Remove or disable the offending metric declaration in the connector.
- Check the reported class SimpleName in the message to identify which plugin/metric is at fault.
Example fix
// before
return new Metric() { ... }; // custom implementation
// after
private final Counter rows = new CounterImpl();
public Counter getRows() { return rows; } Defensive patterns
Strategy: type-guard
Validate before calling
if (!(metric instanceof Counter) && !(metric instanceof Meter)) {
throw new IllegalArgumentException("metric type not probeable: " + metric.getClass().getName());
} Type guard
static boolean isProbeableMetric(Object m) {
return m instanceof Counter || m instanceof Meter;
} Try / catch
try {
metricsContext.provideDynamicMetrics(...);
} catch (SeaTunnelException e) {
if (e.getMessage().startsWith("The value of Metric does not support")) {
log.warn("unprobeable metric skipped: {}", e.getMessage());
} else throw e;
} Prevention
- Use only Counter/Meter implementations from the engine API in connectors.
- Rebuild plugins against the exact engine version to keep class identity consistent.
- Keep one SeaTunnel API jar on the classpath - no mixed versions.
When it happens
Trigger: A registered connector metric object's runtime class is neither Counter nor Meter (e.g. a custom Metric subclass or Gauge) when metrics are probed via provideDynamicMetrics, typically triggered by a metrics scrape or the SeaTunnel web UI.
Common situations: Custom connectors with custom Metric implementations; classpath mixing different metric API versions so an object that looks like a Counter is not java.util.function-type-matching; plugins compiled against a different SeaTunnel API version.
Related errors
- Unsupported metric class: ${metricClass}
- Unsupported convert %s to Map, typeDefine: %s
- Unsupported convert %s to Array, typeDefine: %s
- Unsupported convert ${value.getClass()} to Row, typeDefine:
- Unsupported convert ${value.getClass()} to byte[], typeDefin
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/7695a83561deae15.
Report an issue: GitHub.