apache/druid · error · ISE

If configured, 'druid.broker.segment.ignoredTiers' must be…

Error message

If configured, 'druid.broker.segment.ignoredTiers' must be non-empty

What it means

BrokerServerView.validateSegmentWatcherConfig() rejects an ignoredTiers config that is present but empty. Ignoring zero tiers is a no-op and indicates a misconfiguration, so the property must either be absent or list at least one tier.

Solutions

  1. Remove the druid.broker.segment.ignoredTiers property entirely or populate it with at least one tier, e.g. ignoredTiers=cold.
  2. Confirm the tier names match the historicals' druid.server.tier values.
  3. Restart the broker after the config change.

Example fix

// before
druid.broker.segment.ignoredTiers=
// after
druid.broker.segment.ignoredTiers=cold
Defensive patterns

Strategy: validation

Validate before calling

List<String> ignored = getTierList(props, "druid.broker.segment.ignoredTiers");
if (ignored != null && ignored.isEmpty()) {
  throw new IllegalStateException("ignoredTiers configured but empty; remove it or list tiers");
}

Prevention

When it happens

Trigger: Setting druid.broker.segment.ignoredTiers= (empty value) or an empty list in broker runtime.properties, producing a non-null empty list passed to BrokerServerView.

Common situations: Blanking out the property after decommissioning a tier; template-generated configs emitting empty values; mixing up watchedTiers/ignoredTiers edits.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at server/src/main/java/org/apache/druid/client/BrokerServerView.java:247

   */
  private void validateSegmentWatcherConfig(BrokerSegmentWatcherConfig watcherConfig)
  {
    if (watcherConfig.getWatchedTiers() != null
        && watcherConfig.getIgnoredTiers() != null) {
      throw new ISE(
          "At most one of 'druid.broker.segment.watchedTiers' "
          + "and 'druid.broker.segment.ignoredTiers' can be configured."
      );
    }

    if (watcherConfig.getWatchedTiers() != null
        && watcherConfig.getWatchedTiers().isEmpty()) {
      throw new ISE("If configured, 'druid.broker.segment.watchedTiers' must be non-empty");
    }

    if (watcherConfig.getIgnoredTiers() != null
        && watcherConfig.getIgnoredTiers().isEmpty()) {
      throw new ISE("If configured, 'druid.broker.segment.ignoredTiers' must be non-empty");
    }
  }

  private QueryableDruidServer addServer(DruidServer server)
  {
    QueryableDruidServer retVal = druidClientFactory.make(server);
    QueryableDruidServer exists = clients.put(server.getName(), retVal);
    if (exists != null) {
      log.warn("QueryRunner for server[%s] already exists!? Well it's getting replaced", server);
    }

    return retVal;
  }

  private QueryableDruidServer removeServer(DruidServer server)
  {
    for (DataSegment segment : server.iterateAllSegments()) {
      serverRemovedSegment(server.getMetadata(), segment);

View on GitHub (pinned to 9b90983fd2)