apache/druid · warning

Registration already in progress for serviceId

Error message

Registration already in progress for serviceId [%s]

What it means

Emitted in ConsulDruidNodeAnnouncer.announce when a concurrent announce() call for the same serviceId is already underway. A set of in-flight registrations (registeringNodes) guards against duplicate concurrent registrations; if add() returns false, this call is skipped and the in-flight one will complete registration.

Solutions

  1. Usually no action needed: the concurrent call completes the registration; verify the service appears in Consul.
  2. If seen persistently, find the duplicate caller and serialize lifecycle start of the announcer.
  3. Ensure the code path that triggers announce isn't invoked both by lifecycle start and a listener callback.

Example fix

// before: announce called from two paths simultaneously
leaderListener.becomeLeader() -> announce(...)
lifecycle.start()           -> announce(...)
// after: guard with lifecycle
if (lifecycleStage == STARTED) { announce(...); } // single entry point only
Defensive patterns

Strategy: try-catch

Try / catch

try {
  announcer.announce(node);
} catch (RuntimeException e) {
  // treat 'already in progress' as benign; log and continue
}

Prevention

When it happens

Trigger: Two threads calling announce() nearly simultaneously for the same DiscoveryDruidNode/serviceId — e.g. Druid lifecycle racing with a leadership change or repeated announcer start.

Common situations: Concurrent lifecycle events (leader election, task restart) triggering announce on overlapping threads; announcer start() racing an external announce call.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/0163e9e660da970e. Report an issue: GitHub.

Appendix: source

Thrown at extensions-contrib/consul-extensions/src/main/java/org/apache/druid/consul/discovery/ConsulDruidNodeAnnouncer.java:152

      }
    }

    announcedNodes.clear();
    lifecycleLock.exitStop();
  }

  @Override
  public void announce(DiscoveryDruidNode discoveryDruidNode)
  {
    if (!lifecycleLock.awaitStarted(1, TimeUnit.SECONDS)) {
      throw new ISE("Announcer not started");
    }

    String serviceId = ConsulServiceIds.serviceId(config, discoveryDruidNode);

    // Prevent concurrent duplicate registrations for the same serviceId
    if (!registeringNodes.add(serviceId)) {
      LOGGER.warn("Registration already in progress for serviceId [%s]", serviceId);
      return;
    }

    try {
      // If already announced, skip duplicate registration
      if (announcedNodes.containsKey(serviceId)) {
        LOGGER.warn("ServiceId [%s] already announced, skipping", serviceId);
        return;
      }

      long registerStart = System.nanoTime();

      // Register in Consul, then track locally atomically in this block
      registerServiceWithRetry(serviceId, discoveryDruidNode);
      announcedNodes.put(serviceId, discoveryDruidNode);

      long registerLatency = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - registerStart);
      ConsulMetrics.emitTimer(emitter, "consul/register/latency", registerLatency,

View on GitHub (pinned to 9b90983fd2)