apache/seatunnel · warning

Name collision: MetricsContext already contains a Metric wit

Error message

Name collision: MetricsContext already contains a Metric with the name '{}'. Metric will not be reported.

What it means

AbstractMetricsContext.addMetric detects a name collision when putting a Metric into the metrics map: if a Metric already exists under that name, the original metric is restored and the new one is discarded with a warning. Duplicate metric names mean one of the two metrics will never be reported.

Source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/common/metrics/AbstractMetricsContext.java:69

        }
        return this.meter(name, new ThreadSafeQPSMeter(name));
    }

    @Override
    public <M extends Meter> M meter(String name, M meter) {
        this.addMetric(name, meter);
        return meter;
    }

    protected void addMetric(String name, Metric metric) {
        if (metric == null) {
            log.warn("Ignoring attempted add of a metric due to being null for name {}.", name);
        } else {
            synchronized (this) {
                Metric prior = this.metrics.put(name, metric);
                if (prior != null) {
                    this.metrics.put(name, prior);
                    log.warn(
                            "Name collision: MetricsContext already contains a Metric with the name '"
                                    + name
                                    + "'. Metric will not be reported.");
                }
            }
        }
    }

    @Override
    public String toString() {
        return "AbstractMetricsContext{" + "metrics=" + metrics + '}';
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Uniquify metric names by including subtask/parallelism/table identifiers, e.g. name + "#" + subtaskIndex.
  2. Guard registration with a check that the name is not already present before calling counter()/meter().
  3. Move metric registration to one-time initialization (open/init) rather than per-record or per-retry paths.
  4. If re-registration is intended, remove the old metric first.

Example fix

// before
context.counter("records_received"); // collides on retry
context.counter("records_received");
// after
String name = "records_received#" + context.getIndexOfSubtask();
if (!metricsContext.contains(name)) {
    context.counter(name);
}
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
if (!seen.add(metricName)) throw new IllegalStateException("duplicate metric name: " + metricName);

Type guard

if (existingMetrics.containsKey(metricName)) { metricName = metricName + "#" + subtaskIndex; }

Try / catch

// warning-only path; prevent duplicates rather than catching

Prevention

When it happens

Trigger: Calling counter(name)/meter(name)/addMetric(name, metric) twice with the same metric name within the same MetricsContext, e.g. re-registering metrics on task retry or across overlapping component lifecycles.

Common situations: Source/sink or transform plugins registering metrics with hard-coded names that collide across subtasks; checkpoint restart re-invoking initialization code; copy-pasted metric names within one pipeline.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/c6b93463fc5c8f25. Report an issue: GitHub.