apache/seatunnel · error · IllegalArgumentException
Unsupported metric class: ${metricClass}
Error message
Unsupported metric class: ${metricClass} What it means
ConnectorMetricsCalcContext.createMetric instantiates a metric from a MetricsContext by class: only Counter and Meter are supported. If a connector declares a metric of another class (e.g. Gauge, Histogram, DistributionSummary), IllegalArgumentException 'Unsupported metric class' is thrown when the metric is created via newMetric.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/metrics/ConnectorMetricsCalcContext.java:334
} else {
String metricName =
PluginType.SINK.equals(type)
? sinkMetric + "#" + tableName
: sourceMetric + "#" + tableName;
T newMetric = createMetric(metricsContext, metricName, cls);
processor.process(newMetric);
metricMap.put(tableName, newMetric);
}
}
private <T> T createMetric(
MetricsContext metricsContext, String metricName, Class<T> metricClass) {
if (metricClass == Counter.class) {
return metricClass.cast(metricsContext.counter(metricName));
} else if (metricClass == Meter.class) {
return metricClass.cast(metricsContext.meter(metricName));
}
throw new IllegalArgumentException("Unsupported metric class: " + metricClass.getName());
}
@FunctionalInterface
interface MetricProcessor<T> {
void process(T t);
}
private static final class PendingMetrics {
private long count;
private long bytes;
private final Map<String, TablePendingMetrics> tableMetrics = new ConcurrentHashMap<>();
void add(String tableName, long rowBytes) {
count++;
bytes += rowBytes;
if (StringUtils.isNotBlank(tableName)) {
tableMetrics
.computeIfAbsent(tableName, key -> new TablePendingMetrics())View on GitHub (pinned to cf67b549a7)
Solutions
- Change the connector metric to a supported type: Counter for counts, Meter for rates.
- If you need gauge-like values, model them as a Counter updated by the connector.
- Check the SeaTunnel version - newer metric types may require upgrading the engine.
- Fix any generic metric factory code that passes unexpected Class<T> values into createMetric.
Example fix
// before @Metric Gauge<Double> queueSize(); // after @Metric Counter enqueuedCount();
Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = metric.getMetric().getClass();
if (c != Counter.class && c != Meter.class) {
throw new IllegalArgumentException("connector metric must be Counter or Meter: " + c.getName());
} Type guard
static boolean isSupportedMetric(Object m) {
return m instanceof Counter || m instanceof Meter;
} Try / catch
try {
MetricsContext.register(connectorMetrics);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported metric class")) {
log.warn("skipping unsupported metric: {}", e.getMessage());
} else throw e;
} Prevention
- Declare connector metrics only as Counter or Meter.
- Write a unit test that instantiates every @Metric in your connector.
- Pin connector builds to the same SeaTunnel API version as the engine.
When it happens
Trigger: A Source/Sink/Transform declares a metric via @Metric with a getMetric() returning a type other than Counter or Meter, and the metrics system calls newMetric -> createMetric for that connector metric during job metric initialization.
Common situations: Custom connector exposing a Gauge or Histogram metric; connector code updated to a new metric type not yet supported by the engine's metrics bridge; generic helper returning Object cast to an unsupported Class<T>.
Related errors
- The value of Metric does not support ${metricType} data type
- Unsupported type in LocalTimeArrayType: ${eleSqlType}
- Unsupported type: ${sqlType}
- Unsupported type: ${clazz}
- The connector of option is none
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/04f2616d2296718a.
Report an issue: GitHub.