apache/druid · error · ISE

At most one of 'druid.broker.segment.watchedTiers' and…

Error message

At most one of 'druid.broker.segment.watchedTiers' and 'druid.broker.segment.ignoredTiers' can be configured.

What it means

BrokerServerView.validateSegmentWatcherConfig() enforces that watchedTiers and ignoredTiers are mutually exclusive: the broker may either watch only listed tiers or ignore listed tiers, but configuring both is contradictory. It throws immediately when the BrokerSegmentWatcherConfig has both non-null.

Solutions

  1. Remove one of the two properties from the broker config; keep only watchedTiers or only ignoredTiers.
  2. If an empty property is unintentionally creating a non-null list, delete the property line rather than leaving it blank.
  3. Restart the broker after updating runtime.properties.

Example fix

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

Strategy: validation

Validate before calling

boolean hasWatched = props.containsKey("druid.broker.segment.watchedTiers");
boolean hasIgnored = props.containsKey("druid.broker.segment.ignoredTiers");
if (hasWatched && hasIgnored) {
  throw new IllegalStateException("Set only one of watchedTiers or ignoredTiers");
}

Prevention

When it happens

Trigger: Setting both druid.broker.segment.watchedTiers and druid.broker.segment.ignoredTiers to non-null lists in broker runtime.properties (an empty string still yields a non-null list, which also triggers this).

Common situations: Copy-pasting both properties from example configs; merging config files that each set one of the properties; leaving watchedTiers= empty while also setting ignoredTiers.

Related errors


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

Appendix: source

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

  public QueryableDruidServer.Maker getDruidClientFactory()
  {
    return druidClientFactory;
  }

  /**
   * Validates the given BrokerSegmentWatcherConfig.
   * <ul>
   *   <li>At most one of watchedTiers or ignoredTiers can be set</li>
   *   <li>If set, watchedTiers must be non-empty</li>
   *   <li>If set, ignoredTiers must be non-empty</li>
   * </ul>
   */
  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)
  {

View on GitHub (pinned to 9b90983fd2)