apache/druid · warning

Ignore unparseable DruidService for [%s]: %s

Error message

Ignore unparseable DruidService for [%s]: %s

What it means

Log warning in DiscoveryDruidNode.fromJson. When deserializing a node announcement, any entry in the services map that cannot be converted to a DruidService via the JSON mapper is skipped, so the node is discovered but missing that service capability. This lets the cluster tolerate version skew where a newer node announces an unknown service type.

Source

Thrown at server/src/main/java/org/apache/druid/discovery/DiscoveryDruidNode.java:131

  @JsonCreator
  private static DiscoveryDruidNode fromJson(
      @JsonProperty("druidNode") DruidNode druidNode,
      @JsonProperty("nodeType") NodeRole nodeRole,
      @JsonProperty("services") Map<String, Object> rawServices,
      @JsonProperty("startTime") DateTime startTime,
      @JsonProperty("availableProcessors") Integer availableProcessors,
      @JsonProperty("totalMemory") Long totalMemory,
      @JacksonInject ObjectMapper jsonMapper
  )
  {
    Map<String, DruidService> services = new HashMap<>();
    if (rawServices != null && !rawServices.isEmpty()) {
      for (Entry<String, Object> entry : rawServices.entrySet()) {
        try {
          services.put(entry.getKey(), jsonMapper.convertValue(entry.getValue(), DruidService.class));
        }
        catch (RuntimeException e) {
          LOG.warn("Ignore unparseable DruidService for [%s]: %s", druidNode.getHostAndPortToUse(), entry.getValue());
        }
      }
    }
    return new DiscoveryDruidNode(druidNode, nodeRole, services, startTime, availableProcessors, totalMemory);
  }

  @JsonProperty
  public Map<String, DruidService> getServices()
  {
    return services;
  }

  /**
   * Keeping the legacy name 'nodeType' property name for backward compatibility. When the project is updated to
   * Jackson 2.9 it could be changed, see https://github.com/apache/druid/issues/7152.
   */
  @JsonProperty("nodeType")
  public NodeRole getNodeRole()

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Upgrade all cluster nodes to the same Druid version so service classes match.
  2. Identify the offending service key in the log payload and check whether the reading node's extensions include the module providing it.
  3. Check the announcing node's logs for errors serializing its services.
  4. Ignore if the missing service is not needed by this watcher's listeners.
Defensive patterns

Strategy: validation

Validate before calling

// Validate announced service JSON before use
for (var e : rawServices.entrySet()) {
  try { mapper.convertValue(e.getValue(), DruidService.class); }
  catch (RuntimeException ex) { log.warn("Skipping unparseable service %s", e.getKey()); }
}

Try / catch

try {
  DruidService svc = jsonMapper.convertValue(value, DruidService.class);
} catch (RuntimeException e) {
  log.warn("Ignoring unparseable service %s", value);
}

Prevention

When it happens

Trigger: A node in the cluster announces a service key whose JSON shape does not match any DruidService subtype (e.g. a service added in a newer Druid version, or corrupted/malformed service data in its announcement).

Common situations: Rolling upgrades where nodes of mixed Druid versions announce new service types; custom forks or extensions registering services not on the consuming node's classpath; manually edited or corrupted ZK data.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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