apache/druid · warning

ServiceId [ ] already announced, skipping

Error message

ServiceId [%s] already announced, skipping

What it means

Emitted in ConsulDruidNodeAnnouncer.announce when the serviceId is already present in announcedNodes, meaning the node was previously registered with Consul. The call is a no-op and skipped to avoid redundant or duplicate service registration.

Solutions

  1. No action required — this is expected idempotent behavior; the service remains registered.
  2. If you intended to refresh registration, call unannounce() first, then announce() again.
  3. If seen unexpectedly, audit which component calls announce twice and remove the redundant call.

Example fix

// before
announcer.announce(node); // called again after re-election
// after
if (!isAnnounced(node)) { announcer.announce(node); } // or rely on the built-in skip
Defensive patterns

Strategy: try-catch

Try / catch

try {
  announcer.announce(node);
} catch (RuntimeException e) {
  // skip if serviceId already announced
}

Prevention

When it happens

Trigger: Calling announce() for a node whose serviceId is already registered and tracked — e.g. re-invoking announce after lifecycle restart, or a redundant announce from a second code path.

Common situations: Restarting the announcer lifecycle without stop() having deregistered; scripts/leadership logic re-announcing unchanged nodes.

Related errors


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

Appendix: source

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

  @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,
          "role", discoveryDruidNode.getNodeRole().getJsonName());

      LOGGER.info("Successfully announced serviceId [%s]", serviceId);
      ConsulMetrics.emitCount(
          emitter,
          "consul/announce/success",
          "role",

View on GitHub (pinned to 9b90983fd2)