apache/skywalking · critical · UnexpectedException

Duplicate worker name:{remoteReceiverWorkName}

Error message

Duplicate worker name:{remoteReceiverWorkName}

What it means

WorkerInstancesService.put() registers stream-processor workers (metrics dispatch endpoints) in a name-keyed map used for inter-OAP remote forwarding in cluster mode. Names must be unique process-wide; registering a second worker under an existing remoteReceiverWorkName throws UnexpectedException('Duplicate worker name:...'). It fires during OAP startup when stream pipelines (mostly OAL-generated metrics workers) are wired.

Source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/worker/WorkerInstancesService.java:50

public class WorkerInstancesService implements IWorkerInstanceSetter, IWorkerInstanceGetter {
    private static final Logger LOGGER = LoggerFactory.getLogger(WorkerInstancesService.class);

    private final Map<String, RemoteHandleWorker> instances;

    public WorkerInstancesService() {
        this.instances = new HashMap<>();
    }

    @Override
    public RemoteHandleWorker get(String nextWorkerName) {
        return instances.get(nextWorkerName);
    }

    @Override
    public void put(String remoteReceiverWorkName, AbstractWorker instance,
                    MetricStreamKind kind, Class<? extends StreamData> streamDataClass) {
        if (instances.containsKey(remoteReceiverWorkName)) {
            throw new UnexpectedException("Duplicate worker name:" + remoteReceiverWorkName);
        }
        instances.put(remoteReceiverWorkName, new RemoteHandleWorker(instance, kind, streamDataClass));
        LOGGER.debug("Worker {} has been registered as {}", instance.toString(), remoteReceiverWorkName);
    }

    @Override
    public void remove(String remoteReceiverWorkName) {
        final RemoteHandleWorker removed = instances.remove(remoteReceiverWorkName);
        if (removed != null) {
            LOGGER.debug("Worker {} has been deregistered", remoteReceiverWorkName);
        }
    }
}

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Identify the duplicate name in the message and grep your OAL/MAL/LAL rule files for a metric (or dispatcher target) with that name; rename one of them.
  2. Check that rule files are not loaded twice via configuration (e.g. both a packaged rule and a custom override of the same metric).
  3. After upgrading OAP, diff your custom metrics against the newly built-in ones — a rename in core may now collide.
  4. Restart OAP once fixed.

Example fix

// custom.oal — before
endpoint_qps_5m = from(Endpoint.*).sum()   // collides with built-in worker

// after
my_endpoint_qps_5m = from(Endpoint.*).sum()
Defensive patterns

Strategy: validation

Validate before calling

// CI check: no duplicate output metric names across OAL files
Set<String> seen = new HashSet<>();
for (String metricName : allOalMetricNames()) {
    if (!seen.add(metricName)) throw new BuildFailure("duplicate worker/metric name: " + metricName);
}

Try / catch

Not applicable — fail-fast at startup is desired; rename the colliding metric instead of catching.

Prevention

When it happens

Trigger: Two stream workers registered with the same worker/dispatch name — typically two OAL metrics producing the same downstream worker name, or a custom metric/OAL rule that collides with an existing one; occurs at boot while put() is called during node role/stream registration (especially with cluster module remote handlers).

Common situations: Adding a custom OAL metric whose name duplicates a built-in metric; multiple OAL scripts defining the same metric name; upgrading OAP where a rule file was loaded twice (config includes both old and new rule files); copy-pasting MAL/OAL rules without renaming outputs.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/cfdf66cf7351e35b. Report an issue: GitHub.