apache/druid · warning

Could not determine DruidNode for DiscoveryDruidNode

Error message

Could not determine DruidNode for DiscoveryDruidNode[%s]

What it means

BaseDynamicConfigSyncer converts DiscoveryDruidNode entries (from the cluster view) into ServiceLocation objects for dynamic config sync. If a discovered node has no DruidNode attached, the converter logs this warning and returns null, meaning that node is excluded from sync targets (e.g. broker list). It signals a node advertised itself to the discovery/DruidNodeService without complete node data.

Solutions

  1. Inspect the offending node's registration (look at its logs/startup) so it registers with a valid DruidNode
  2. Check for extension or custom service-emitting code that constructs DiscoveryDruidNode without a DruidNode
  3. Restart the misbehaving node so it re-registers fully in the cluster view

Example fix

// before (extension code)
new DiscoveryDruidNode(null, NodeType.BROKER, null)
// after
new DiscoveryDruidNode(new DruidNode("broker", host, true, port, null, TLSMode.DISABLED, false), NodeType.BROKER, null)
Defensive patterns

Strategy: type-guard

Validate before calling

if (discoveryNode.getDruidNode() == null) { skip; }

Type guard

Optional<ServiceLocation> toLocation(DiscoveryDruidNode n) { return Optional.ofNullable(n).map(DiscoveryDruidNode::getDruidNode).filter(Objects::nonNull).map(d -> new ServiceLocation(d.getHost(), d.getPlaintextPort(), ...)); }

Try / catch

try { ServiceLocation loc = syncer.brokerLocation(node); if (loc == null) { LOG.warn("Node {} has no DruidNode; excluding", node); } } catch (Exception e) { /* treat as unavailable */ }

Prevention

When it happens

Trigger: brokerLocation() (or syncer refresh) encounters a DiscoveryDruidNode whose getDruidNode() is null — e.g. a node registered an empty/partial DiscoveryDruidNode in the service inventory, or a node type that does not carry a DruidNode.

Common situations: Partially started or misconfigured service announcing itself; custom node types/extensions emitting DiscoveryDruidNode without the inner node; transient cluster-view inconsistencies.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at server/src/main/java/org/apache/druid/server/http/BaseDynamicConfigSyncer.java:261

  /**
   * Adds a broker to the set of inSyncBrokers if the dynamic config has not changed.
   */
  private synchronized void markBrokerAsSynced(DynamicConfig config, ServiceLocation broker)
  {
    if (config.equals(lastKnownConfig.get())) {
      inSyncBrokers.add(new BrokerSyncStatus(broker, System.currentTimeMillis()));
    }
  }

  /**
   * Utility method to convert {@link DiscoveryDruidNode} to a {@link ServiceLocation}
   */
  @Nullable
  private static ServiceLocation convertDiscoveryNodeToServiceLocation(DiscoveryDruidNode discoveryDruidNode)
  {
    final DruidNode druidNode = discoveryDruidNode.getDruidNode();
    if (druidNode == null) {
      log.warn("Could not determine DruidNode for DiscoveryDruidNode[%s]", discoveryDruidNode);
      return null;
    }

    return new ServiceLocation(
        druidNode.getHost(),
        druidNode.getPlaintextPort(),
        druidNode.getTlsPort(),
        ""
    );
  }

  private void emitStat(CoordinatorStat stat, RowKey rowKey, long value)
  {
    ServiceMetricEvent.Builder eventBuilder = new ServiceMetricEvent.Builder();
    rowKey.getValues().forEach(
        (dim, dimValue) -> eventBuilder.setDimension(dim.reportedName(), dimValue)
    );
    emitter.emit(eventBuilder.setMetric(stat.getMetricName(), value));

View on GitHub (pinned to 9b90983fd2)