{"record":{"id":"b00a876604ab2364","repo":"apache/druid","slug":"if-configured-druid-broker-segment-watchedtiers","errorCode":null,"errorMessage":"If configured, 'druid.broker.segment.watchedTiers' must be non-empty","messagePattern":"If configured, 'druid\\.broker\\.segment\\.watchedTiers' must be non-empty","errorType":"exception","errorClass":"ISE","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/client/BrokerServerView.java","lineNumber":242,"sourceCode":"   * <ul>\n   *   <li>At most one of watchedTiers or ignoredTiers can be set</li>\n   *   <li>If set, watchedTiers must be non-empty</li>\n   *   <li>If set, ignoredTiers must be non-empty</li>\n   * </ul>\n   */\n  private void validateSegmentWatcherConfig(BrokerSegmentWatcherConfig watcherConfig)\n  {\n    if (watcherConfig.getWatchedTiers() != null\n        && watcherConfig.getIgnoredTiers() != null) {\n      throw new ISE(\n          \"At most one of 'druid.broker.segment.watchedTiers' \"\n          + \"and 'druid.broker.segment.ignoredTiers' can be configured.\"\n      );\n    }\n\n    if (watcherConfig.getWatchedTiers() != null\n        && watcherConfig.getWatchedTiers().isEmpty()) {\n      throw new ISE(\"If configured, 'druid.broker.segment.watchedTiers' must be non-empty\");\n    }\n\n    if (watcherConfig.getIgnoredTiers() != null\n        && watcherConfig.getIgnoredTiers().isEmpty()) {\n      throw new ISE(\"If configured, 'druid.broker.segment.ignoredTiers' must be non-empty\");\n    }\n  }\n\n  private QueryableDruidServer addServer(DruidServer server)\n  {\n    QueryableDruidServer retVal = druidClientFactory.make(server);\n    QueryableDruidServer exists = clients.put(server.getName(), retVal);\n    if (exists != null) {\n      log.warn(\"QueryRunner for server[%s] already exists!? Well it's getting replaced\", server);\n    }\n\n    return retVal;\n  }","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/client/BrokerServerView.java#L224-L260","documentation":"BrokerServerView.validateSegmentWatcherConfig() rejects a watchedTiers config that is present but empty. Watching zero tiers is meaningless (no segments would ever be watched), so the property must either be absent or contain at least one tier name.","triggerScenarios":"Setting druid.broker.segment.watchedTiers= (empty value) or druid.broker.segment.watchedTiers=[] in broker runtime.properties, producing a non-null empty list passed to BrokerServerView.","commonSituations":"Clearing the tier list by deleting the values but keeping the property; templated configs emitting empty keys; mistyping intended tier names then removing them but not the property.","solutions":["Either remove the druid.broker.segment.watchedTiers property entirely (watch all tiers) or list at least one tier, e.g. watchedTiers=hot.","Verify tier names match those the historicals announce (druid.server.tier).","Restart the broker after the config change."],"exampleFix":"// before\ndruid.broker.segment.watchedTiers=\n// after\ndruid.broker.segment.watchedTiers=hot,_default_tier","handlingStrategy":"validation","validationCode":"List<String> watched = getTierList(props, \"druid.broker.segment.watchedTiers\");\nif (watched != null && watched.isEmpty()) {\n  throw new IllegalStateException(\"watchedTiers configured but empty; remove it or list tiers\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Delete the property line instead of leaving an empty value.","Verify tier names against historicals' druid.server.tier values.","Validate broker configs at deploy time."],"tags":["druid","broker","configuration","segment-tiers"],"backgroundTag":"invalid-config-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}